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.
10 # checkAPIs.pl [-M] [-g group1] [-g group2] [-s summary-group1] [-s summary-group2] [--nocheck-value-string-array-null-termination] file1 file2 ...
14 # Wireshark - Network traffic analyzer
15 # By Gerald Combs <gerald@wireshark.org>
16 # Copyright 1998 Gerald Combs
18 # This program is free software; you can redistribute it and/or
19 # modify it under the terms of the GNU General Public License
20 # as published by the Free Software Foundation; either version 2
21 # of the License, or (at your option) any later version.
23 # This program is distributed in the hope that it will be useful,
24 # but WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 # GNU General Public License for more details.
28 # You should have received a copy of the GNU General Public License
29 # along with this program; if not, write to the Free Software
30 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 # Group name, e.g. 'prohibited'
40 # 'count_errors' => 1, # 1 if these are errors, 0 if warnings
41 # 'functions' => [ 'f1', 'f2', ...], # Function array
42 # 'function-counts' => {'f1',0, 'f2',0, ...}, # Function Counts hash (initialized in the code)
45 # APIs that MUST NOT be used in Wireshark
46 'prohibited' => { 'count_errors' => 1, 'functions' => [
48 # Use something that won't overwrite the end of your buffer instead
60 # use glib (g_*) versions instead of these:
68 # use memset, memcpy, memcmp instead of these:
72 # use ep_*, se_*, or g_* functions instead of these:
73 # (One thing to be aware of is that space allocated with malloc()
74 # may not be freeable--at least on Windows--with g_free() and
83 # These may have unexpected behaviors in some locales (e.g.,
84 # "I" isn't always the upper-case form of "i", and "i" isn't
85 # always the lower-case form of "I"). Use the g_ascii_* version
95 # Use the ws_* version of these:
96 # (Necessary because on Windows we use UTF8 for throughout the code
97 # so we must tweak that to UTF16 before operating on the file. Code
98 # using these functions will work unless the file/path name contains
109 'tmpnam' # use mkstemp
112 # APIs that SHOULD NOT be used in Wireshark (any more)
113 'deprecated' => { 'count_errors' => 1, 'functions' => [
114 'perror', # Use strerror() and report messages in whatever
115 # fashion is appropriate for the code in question.
116 'ctime', # Use abs_time_secs_to_str()
117 ### Deprecated GLib/GObject functions/macros
118 # (The list is based upon the GLib 2.24.1 & GObject 2.24.1 documentation;
119 # Some of the entries are commented out since they are currently
120 # being used in Wireshark and since the replacement functionality
121 # is not available in all the GLib versions that Wireshark
122 # currently supports (ie: versions starting with GLib 2.4).
125 'g_allocator_free', # "use slice allocator" (avail since 2.10,2.14)
126 'g_allocator_new', # "use slice allocator" (avail since 2.10,2.14)
127 'g_async_queue_ref_unlocked', # g_async_queue_ref() (OK since 2.8)
128 'g_async_queue_unref_and_unlock', # g_async_queue_unref() (OK since 2.8)
130 'g_cache_value_foreach', # g_cache_key_foreach()
131 'g_date_set_time', # g_date_set_time_t (avail since 2.10)
134 'G_GNUC_PRETTY_FUNCTION',
135 'g_hash_table_freeze',
138 'g_io_channel_close',
141 'g_io_channel_write',
142 'g_list_pop_allocator', # "does nothing since 2.10"
143 'g_list_push_allocator', # "does nothing since 2.10"
151 'g_main_set_poll_func',
152 'g_node_pop_allocator', # "does nothing since 2.10"
153 'g_node_push_allocator', # "does nothing since 2.10"
154 'g_scanner_add_symbol',
155 'g_scanner_remove_symbol',
156 'g_scanner_foreach_symbol',
157 'g_scanner_freeze_symbol_table',
158 'g_scanner_thaw_symbol_table',
159 'g_slist_pop_allocator', # "does nothing since 2.10"
160 'g_slist_push_allocator', # "does nothing since 2.10"
161 'g_string_sprintf', # use g_string_printf() instead
162 'g_string_sprintfa', # use g_string_append_printf instead
164 'g_value_set_boxed_take_ownership',
165 'g_value_set_object_take_ownership',
166 'g_value_set_param_take_ownership',
167 'g_value_set_string_take_ownership',
168 'G_WIN32_DLLMAIN_FOR_DLL_NAME',
169 'g_win32_get_package_installation_directory',
170 'g_win32_get_package_installation_subdirectory',
172 ## Following Deprecated as of GLib 2.10; to be replaced only when Wireshark requires GLib 2.10 or later
173 ## Note: Only the commented out items are currently used by Wireshark
174 ### GMemChunks should used *only* with GLib < 2.10.
175 ### There's an issue wherein GLib >= 2.10 g_mem_chunk_destroy doesn't actually free memory thus
176 ### leading to memory leaks.
177 ### So: either replace GMemChunk use with something else altogether
178 ### or use GMemChunks for GLib < 2.10 and GSlice (or whatever) for newer GLibs.
179 ## 2.10 'g_mem_chunk_alloc', # "use slice allocator" (avail since 2.10)
180 ## 2.10 'g_mem_chunk_alloc0', # "use slice allocator" (avail since 2.10)
181 'g_mem_chunk_clean', # "use slice allocator" (avail since 2.10)
182 ## 2.10 'g_mem_chunk_create', # "use slice allocator" (avail since 2.10)
183 ## 2.10 'g_mem_chunk_destroy', # "use slice allocator" (avail since 2.10)
184 ## 2.10 'g_mem_chunk_free', # "use slice allocator" (avail since 2.10)
185 'g_mem_chunk_info', # "use slice allocator" (avail since 2.10)
186 ## 2.10 'g_mem_chunk_new', # "use slice allocator" (avail since 2.10)
187 'g_mem_chunk_print', # "use slice allocator" (avail since 2.10)
188 'g_mem_chunk_reset', # "use slice allocator" (avail since 2.10)
189 'g_blow_chunks', # "use slice allocator" (avail since 2.10,2.14)
190 ## 2.10 'g_chunk_free', # g_slice_free (avail since 2.10)
191 ## 2.10 'g_chunk_new', # g_slice_new (avail since 2.10)
192 'g_chunk_new0', # g_slice_new0 (avail since 2.10)
194 ## Following Deprecated as of GLib 2.22;
195 ## Note: Not currently used by Wireshark
196 'g_mapped_file_free', # [as of 2.22: use g_map_file_unref]
199 # APIs that make the program exit. Dissectors shouldn't call these
200 'abort' => { 'count_errors' => 1, 'functions' => [
209 # APIs that print to the terminal. Dissectors shouldn't call these
210 'termoutput' => { 'count_errors' => 0, 'functions' => [
214 # Deprecated GTK APIs
215 # which SHOULD NOT be used in Wireshark (any more).
216 # (Filled in from 'E' entries in %deprecatedGtkFunctions below)
217 'deprecated-gtk' => { 'count_errors' => 1, 'functions' => [
220 # Deprecated GTK APIs yet to be replaced
221 # (Filled in from 'W' entries in %deprecatedGtkFunctions below)
222 'deprecated-gtk-todo' => { 'count_errors' => 0, 'functions' => [
227 # Deprecated GTK+ functions/macros with (E)rror or (W)arning flag:
228 # (The list is based upon the GTK+ 2.20.1 documentation; Some of
229 # the entries are commented out since they are currently
230 # being used in Wireshark and since the replacement functionality
231 # is not available in all the GTK+ versions that Wireshark
232 # currently supports (ie: versions starting with GTK+ 2.4).
233 # E: There should be no current Wireshark use so Error if seen;
234 # W: Not all Wireshark use yet fixed so Warn if seen; (Change to E as fixed)
235 my %deprecatedGtkFunctions = (
236 'gtk_about_dialog_get_name', 'E',
237 'gtk_about_dialog_set_name', 'E',
238 'gtk_accel_group_ref', 'E',
239 'gtk_accel_group_unref', 'E',
240 'gtk_action_block_activate_from', 'E', # since 2.16
241 'gtk_action_connect_proxy', 'E', # since 2.16: use gtk_activatable_set_related_action() (as of 2.16)
242 'gtk_action_disconnect_proxy', 'E', # since 2.16: use gtk_activatable_set_related_action() (as of 2.16)
243 'gtk_action_unblock_activate_from', 'E', # since 2.16
244 'gtk_binding_entry_add', 'E',
245 'gtk_binding_entry_add_signall', 'E',
246 'gtk_binding_entry_clear', 'E',
247 'gtk_binding_parse_binding', 'E',
248 'gtk_box_pack_end_defaults', 'E',
249 'gtk_box_pack_start_defaults', 'E',
250 'gtk_button_box_get_child_ipadding', 'E',
251 'gtk_button_box_get_child_size', 'E',
252 'gtk_button_box_get_spacing', 'E',
253 'gtk_button_box_set_child_ipadding', 'E', # style properties child-internal-pad-x/-y
254 'gtk_button_box_set_child_size', 'E', # style properties child-min-width/-height
255 'gtk_button_box_set_spacing', 'E', # gtk_box_set_spacing [==]
256 'gtk_button_enter', 'E', # since 2.20
257 'gtk_button_leave', 'E', # since 2.20
258 'gtk_button_pressed', 'E', # since 2.20
259 'gtk_button_released', 'E', # since 2.20
260 'gtk_calendar_display_options', 'E',
261 'gtk_calendar_freeze', 'E',
262 'gtk_calendar_thaw', 'E',
263 'GTK_CELL_PIXMAP', 'E', # GtkTreeView (& related) ...
264 'GTK_CELL_PIXTEXT', 'E',
265 'gtk_cell_renderer_editing_canceled', 'E',
266 'GTK_CELL_TEXT', 'W',
267 'GTK_CELL_WIDGET', 'E',
268 'GTK_CHECK_CAST', 'E', # G_TYPE_CHECK_INSTANCE_CAST [==]
269 'GTK_CHECK_CLASS_CAST', 'E', # G_TYPE_CHECK_CLASS_CAST [==]
270 'GTK_CHECK_CLASS_TYPE', 'E', # G_TYPE_CHECK_CLASS_TYPE [==]
271 'GTK_CHECK_GET_CLASS', 'E', # G_TYPE_INSTANCE_GET_CLASS [==]
272 'gtk_check_menu_item_set_show_toggle', 'E', # Does nothing; remove; [show_toggle is always TRUE]
273 'gtk_check_menu_item_set_state', 'E',
274 'GTK_CHECK_TYPE', 'E', # G_TYPE_CHECK_INSTANCE_TYPE [==]
275 'GTK_CLASS_NAME', 'E',
276 'GTK_CLASS_TYPE', 'E',
277 'GTK_CLIST_ADD_MODE', 'E', # GtkTreeView (& related) ...
278 'gtk_clist_append', 'W',
279 'GTK_CLIST_AUTO_RESIZE_BLOCKED', 'E',
280 'GTK_CLIST_AUTO_SORT', 'E',
281 'gtk_clist_clear', 'W',
282 'gtk_clist_column_title_active', 'E',
283 'gtk_clist_column_title_passive', 'E',
284 'gtk_clist_column_titles_active', 'E',
285 'gtk_clist_column_titles_hide', 'E',
286 'gtk_clist_column_titles_passive', 'E',
287 'gtk_clist_column_titles_show', 'W',
288 'gtk_clist_columns_autosize', 'E',
289 'GTK_CLIST_DRAW_DRAG_LINE', 'E',
290 'GTK_CLIST_DRAW_DRAG_RECT', 'E',
291 'gtk_clist_find_row_from_data', 'W',
292 'GTK_CLIST_FLAGS', 'E',
293 'gtk_clist_freeze', 'W',
294 'gtk_clist_get_cell_style', 'E',
295 'gtk_clist_get_cell_type', 'E',
296 'gtk_clist_get_column_title', 'E',
297 'gtk_clist_get_column_widget', 'E',
298 'gtk_clist_get_hadjustment', 'E',
299 'gtk_clist_get_pixmap', 'E',
300 'gtk_clist_get_pixtext', 'E',
301 'gtk_clist_get_row_data', 'W',
302 'gtk_clist_get_row_style', 'E',
303 'gtk_clist_get_selectable', 'E',
304 'gtk_clist_get_selection_info', 'W',
305 'gtk_clist_get_text', 'W',
306 'gtk_clist_get_vadjustment', 'W',
307 'GTK_CLIST_IN_DRAG', 'E',
308 'gtk_clist_insert', 'E',
309 'gtk_clist_moveto', 'W',
310 'gtk_clist_new', 'W',
311 'gtk_clist_new_with_titles', 'E',
312 'gtk_clist_optimal_column_width', 'E',
313 'gtk_clist_prepend', 'E',
314 'gtk_clist_remove', 'W',
315 'GTK_CLIST_REORDERABLE', 'E',
316 'GTK_CLIST_ROW', 'E',
317 'GTK_CLIST_ROW_HEIGHT_SET', 'E',
318 'gtk_clist_row_is_visible', 'W',
319 'gtk_clist_row_move', 'E',
320 'gtk_clist_select_all', 'W',
321 'gtk_clist_select_row', 'W',
322 'gtk_clist_set_auto_sort', 'E',
323 'gtk_clist_set_background', 'W',
324 'gtk_clist_set_button_actions', 'E',
325 'gtk_clist_set_cell_style', 'E',
326 'gtk_clist_set_column_auto_resize', 'W',
327 'gtk_clist_set_column_justification', 'W',
328 'gtk_clist_set_column_max_width', 'E',
329 'gtk_clist_set_column_min_width', 'E',
330 'gtk_clist_set_column_resizeable', 'W',
331 'gtk_clist_set_column_title', 'W',
332 'gtk_clist_set_column_visibility', 'E',
333 'gtk_clist_set_column_widget', 'W',
334 'gtk_clist_set_column_width', 'W',
335 'gtk_clist_set_compare_func', 'W',
336 'GTK_CLIST_SET_FLAG', 'E',
337 'gtk_clist_set_foreground', 'W',
338 'gtk_clist_set_hadjustment', 'E',
339 'gtk_clist_set_pixmap', 'E',
340 'gtk_clist_set_pixtext', 'E',
341 'gtk_clist_set_reorderable', 'E',
342 'gtk_clist_set_row_data', 'W',
343 'gtk_clist_set_row_data_full', 'E',
344 'gtk_clist_set_row_height', 'E',
345 'gtk_clist_set_row_style', 'E',
346 'gtk_clist_set_selectable', 'E',
347 'gtk_clist_set_selection_mode', 'W',
348 'gtk_clist_set_shadow_type', 'W',
349 'gtk_clist_set_shift', 'E',
350 'gtk_clist_set_sort_column', 'W',
351 'gtk_clist_set_sort_type', 'W',
352 'gtk_clist_set_text', 'W',
353 'gtk_clist_set_use_drag_icons', 'E',
354 'gtk_clist_set_vadjustment', 'E',
355 'GTK_CLIST_SHOW_TITLES', 'E',
356 'gtk_clist_sort', 'W',
357 'gtk_clist_swap_rows', 'W',
358 'gtk_clist_thaw', 'W',
359 'gtk_clist_undo_selection', 'E',
360 'gtk_clist_unselect_all', 'W',
361 'gtk_clist_unselect_row', 'E',
362 'GTK_CLIST_UNSET_FLAG', 'E',
363 'GTK_CLIST_USE_DRAG_ICONS', 'E',
364 'gtk_color_selection_get_color', 'E',
365 'gtk_color_selection_set_change_palette_hook', 'E',
366 'gtk_color_selection_set_color', 'E',
367 'gtk_color_selection_set_update_policy', 'E',
368 'gtk_combo_disable_activate', 'W', # GtkComboBoxEntry ... (avail since 2.4/2.6/2.10/2.14)
369 'gtk_combo_new', 'W',
370 'gtk_combo_set_case_sensitive', 'W',
371 'gtk_combo_set_item_string', 'E',
372 'gtk_combo_set_popdown_strings', 'W',
373 'gtk_combo_set_use_arrows', 'E',
374 'gtk_combo_set_use_arrows_always', 'E',
375 'gtk_combo_set_value_in_list', 'E',
376 'gtk_container_border_width', 'E', # gtk_container_set_border_width [==]
377 'gtk_container_children', 'E', # gtk_container_get_children [==]
378 'gtk_container_foreach_full', 'E',
379 'gtk_ctree_collapse', 'E',
380 'gtk_ctree_collapse_recursive', 'E',
381 'gtk_ctree_collapse_to_depth', 'E',
382 'gtk_ctree_expand', 'E',
383 'gtk_ctree_expand_recursive', 'E',
384 'gtk_ctree_expand_to_depth', 'E',
385 'gtk_ctree_export_to_gnode', 'E',
386 'gtk_ctree_find', 'E',
387 'gtk_ctree_find_all_by_row_data', 'E',
388 'gtk_ctree_find_all_by_row_data_custom', 'E',
389 'gtk_ctree_find_by_row_data', 'E',
390 'gtk_ctree_find_by_row_data_custom', 'E',
391 'gtk_ctree_find_node_ptr', 'E',
392 'GTK_CTREE_FUNC', 'E',
393 'gtk_ctree_get_node_info', 'E',
394 'gtk_ctree_insert_gnode', 'E',
395 'gtk_ctree_insert_node', 'E',
396 'gtk_ctree_is_ancestor', 'E',
397 'gtk_ctree_is_hot_spot', 'E',
398 'gtk_ctree_is_viewable', 'E',
399 'gtk_ctree_last', 'E',
400 'gtk_ctree_move', 'E',
401 'gtk_ctree_new', 'E',
402 'gtk_ctree_new_with_titles', 'E',
403 'GTK_CTREE_NODE', 'E',
404 'gtk_ctree_node_get_cell_style', 'E',
405 'gtk_ctree_node_get_cell_type', 'E',
406 'gtk_ctree_node_get_pixmap', 'E',
407 'gtk_ctree_node_get_pixtext', 'E',
408 'gtk_ctree_node_get_row_data', 'E',
409 'gtk_ctree_node_get_row_style', 'E',
410 'gtk_ctree_node_get_selectable', 'E',
411 'gtk_ctree_node_get_text', 'E',
412 'gtk_ctree_node_is_visible', 'E',
413 'gtk_ctree_node_moveto', 'E',
414 'GTK_CTREE_NODE_NEXT', 'E',
415 'gtk_ctree_node_nth', 'E',
416 'GTK_CTREE_NODE_PREV', 'E',
417 'gtk_ctree_node_set_background', 'E',
418 'gtk_ctree_node_set_cell_style', 'E',
419 'gtk_ctree_node_set_foreground', 'E',
420 'gtk_ctree_node_set_pixmap', 'E',
421 'gtk_ctree_node_set_pixtext', 'E',
422 'gtk_ctree_node_set_row_data', 'E',
423 'gtk_ctree_node_set_row_data_full', 'E',
424 'gtk_ctree_node_set_row_style', 'E',
425 'gtk_ctree_node_set_selectable', 'E',
426 'gtk_ctree_node_set_shift', 'E',
427 'gtk_ctree_node_set_text', 'E',
428 'gtk_ctree_post_recursive', 'E',
429 'gtk_ctree_post_recursive_to_depth', 'E',
430 'gtk_ctree_pre_recursive', 'E',
431 'gtk_ctree_pre_recursive_to_depth', 'E',
432 'gtk_ctree_real_select_recursive', 'E',
433 'gtk_ctree_remove_node', 'E',
434 'GTK_CTREE_ROW', 'E',
435 'gtk_ctree_select', 'E',
436 'gtk_ctree_select_recursive', 'E',
437 'gtk_ctree_set_drag_compare_func', 'E',
438 'gtk_ctree_set_expander_style', 'E',
439 'gtk_ctree_set_indent', 'E',
440 'gtk_ctree_set_line_style', 'E',
441 'gtk_ctree_set_node_info', 'E',
442 'gtk_ctree_set_reorderable', 'E',
443 'gtk_ctree_set_show_stub', 'E',
444 'gtk_ctree_set_spacing', 'E',
445 'gtk_ctree_sort_node', 'E',
446 'gtk_ctree_sort_recursive', 'E',
447 'gtk_ctree_toggle_expansion', 'E',
448 'gtk_ctree_toggle_expansion_recursive', 'E',
449 'gtk_ctree_unselect', 'E',
450 'gtk_ctree_unselect_recursive', 'E',
451 'gtk_curve_get_vector', 'E', # since 2.20
452 'gtk_curve_new', 'E', # since 2.20
453 'gtk_curve_reset', 'E', # since 2.20
454 'gtk_curve_set_curve_type', 'E', # since 2.20
455 'gtk_curve_set_gamma', 'E', # since 2.20
456 'gtk_curve_set_range', 'E', # since 2.20
457 'gtk_curve_set_vector', 'E', # since 2.20
458 'gtk_drag_set_default_icon', 'E',
459 'gtk_draw_arrow', 'E',
461 'gtk_draw_box_gap', 'E',
462 'gtk_draw_check', 'E',
463 'gtk_draw_diamond', 'E',
464 'gtk_draw_expander', 'E',
465 'gtk_draw_extension', 'E',
466 'gtk_draw_flat_box', 'E',
467 'gtk_draw_focus', 'E',
468 'gtk_draw_handle', 'E',
469 'gtk_draw_hline', 'E',
470 'gtk_draw_layout', 'E',
471 'gtk_draw_option', 'E',
472 'gtk_draw_polygon', 'E',
473 'gtk_draw_resize_grip', 'E',
474 'gtk_draw_shadow', 'E',
475 'gtk_draw_shadow_gap', 'E',
476 'gtk_draw_slider', 'E',
477 'gtk_draw_string', 'E',
479 'gtk_draw_vline', 'E',
480 'gtk_drawing_area_size', 'E', # >> g_object_set() [==] ?
481 # gtk_widget_set_size_request() [==?]
482 'gtk_entry_append_text', 'E', # >> gtk_editable_insert_text() [==?]
483 'gtk_entry_new_with_max_length', 'E', # gtk_entry_new(); gtk_entry_set_max_length()
484 'gtk_entry_prepend_text', 'E',
485 'gtk_entry_select_region', 'E',
486 'gtk_entry_set_editable', 'E', # >> gtk_editable_set_editable() [==?]
487 'gtk_entry_set_position', 'E',
488 'gtk_exit', 'E', # exit() [==]
489 'gtk_file_chooser_button_new_with_backend', 'E',
490 'gtk_file_chooser_dialog_new_with_backend', 'E',
491 'gtk_file_chooser_widget_new_with_backend', 'E',
492 'gtk_file_selection_complete', 'E',
493 'gtk_file_selection_get_filename', 'E', # GtkFileChooser ...
494 'gtk_file_selection_get_select_multiple', 'E',
495 'gtk_file_selection_get_selections', 'E',
496 'gtk_file_selection_hide_fileop_buttons', 'E',
497 'gtk_file_selection_new', 'E',
498 'gtk_file_selection_set_filename', 'E',
499 'gtk_file_selection_set_select_multiple', 'E',
500 'gtk_file_selection_show_fileop_buttons', 'E',
501 'gtk_fixed_get_has_window', 'E', # gtk_widget_get_has_window() (available since 2.18)
502 'gtk_fixed_set_has_window', 'E', # gtk_widget_set_has_window() (available since 2.18)
503 'gtk_font_selection_dialog_get_apply_button', 'E',
504 'gtk_font_selection_dialog_get_font', 'E',
505 'gtk_font_selection_get_font', 'E', # gtk_font_selection_get_font_name() [!=]
506 'GTK_FUNDAMENTAL_TYPE', 'E',
507 'gtk_gamma_curve_new', 'E', # since 2.20
508 'gtk_hbutton_box_get_layout_default', 'E',
509 'gtk_hbutton_box_get_spacing_default', 'E',
510 'gtk_hbutton_box_set_layout_default', 'E',
511 'gtk_hbutton_box_set_spacing_default', 'E',
513 'gtk_idle_add_full', 'E',
514 'gtk_idle_add_priority', 'E',
515 'gtk_idle_remove', 'E',
516 'gtk_idle_remove_by_data', 'E',
517 'gtk_image_get', 'E',
518 'gtk_image_set', 'E',
519 'gtk_input_add_full', 'W', # >>> g_io_add_watch_full()
520 'gtk_input_dialog_new', 'E', # since 2.20
521 'gtk_input_remove', 'W', # >>> g_source_remove()
522 'GTK_IS_ROOT_TREE', 'E',
523 'gtk_item_factories_path_delete', 'E', # GtkUIManager (avail since 2.4) ...
524 'gtk_item_factory_add_foreign', 'E',
525 'gtk_item_factory_construct', 'E',
526 'gtk_item_factory_create_item', 'W',
527 'gtk_item_factory_create_items', 'E',
528 'gtk_item_factory_create_items_ac', 'W',
529 'gtk_item_factory_create_menu_entries', 'E',
530 'gtk_item_factory_delete_entries', 'E',
531 'gtk_item_factory_delete_entry', 'E',
532 'gtk_item_factory_delete_item', 'W',
533 'gtk_item_factory_from_path', 'E',
534 'gtk_item_factory_from_widget', 'W',
535 'gtk_item_factory_get_item', 'W',
536 'gtk_item_factory_get_item_by_action', 'E',
537 'gtk_item_factory_get_widget', 'W',
538 'gtk_item_factory_get_widget_by_action', 'E',
539 'gtk_item_factory_new', 'W',
540 'gtk_item_factory_path_from_widget', 'E',
541 'gtk_item_factory_popup', 'E',
542 'gtk_item_factory_popup_data', 'E',
543 'gtk_item_factory_popup_data_from_widget', 'E',
544 'gtk_item_factory_popup_with_data', 'E',
545 'gtk_item_factory_set_translate_func', 'E',
546 'gtk_label_get', 'E', # gtk_label_get_text() [!=]
547 'gtk_label_parse_uline', 'E',
548 'gtk_label_set', 'E', # gtk_label_set_text() [==]
549 'gtk_layout_freeze', 'E',
550 'gtk_layout_thaw', 'E',
551 'gtk_list_append_items', 'E',
552 'gtk_list_child_position', 'E',
553 'gtk_list_clear_items', 'E',
554 'gtk_list_end_drag_selection', 'E',
555 'gtk_list_end_selection', 'E',
556 'gtk_list_extend_selection', 'E',
557 'gtk_list_insert_items', 'E',
558 'gtk_list_item_deselect', 'E',
559 'gtk_list_item_new', 'E',
560 'gtk_list_item_new_with_label', 'E',
561 'gtk_list_item_select', 'E',
563 'gtk_list_prepend_items', 'E',
564 'gtk_list_remove_items', 'E',
565 'gtk_list_remove_items_no_unref', 'E',
566 'gtk_list_scroll_horizontal', 'E',
567 'gtk_list_scroll_vertical', 'E',
568 'gtk_list_select_all', 'E',
569 'gtk_list_select_child', 'E',
570 'gtk_list_select_item', 'E',
571 'gtk_list_set_selection_mode', 'E',
572 'gtk_list_start_selection', 'E',
573 'gtk_list_toggle_add_mode', 'E',
574 'gtk_list_toggle_focus_row', 'E',
575 'gtk_list_toggle_row', 'E',
576 'gtk_list_undo_selection', 'E',
577 'gtk_list_unselect_all', 'E',
578 'gtk_list_unselect_child', 'E',
579 'gtk_list_unselect_item', 'E',
580 'gtk_menu_append', 'E', # gtk_menu_shell_append() [==?]
581 'gtk_menu_bar_append', 'E',
582 'gtk_menu_bar_insert', 'E',
583 'gtk_menu_bar_prepend', 'E',
584 'gtk_menu_insert', 'E',
585 'gtk_menu_item_remove_submenu', 'E',
586 'gtk_menu_item_right_justify', 'E',
587 'gtk_menu_prepend', 'E', # gtk_menu_shell_prepend() [==?]
588 'gtk_menu_tool_button_set_arrow_tooltip', 'E',
589 'gtk_notebook_current_page', 'E',
590 'gtk_notebook_query_tab_label_packing', 'E', # since 2.20
591 'gtk_notebook_get_group_id', 'E',
592 'gtk_notebook_set_group_id', 'E',
593 'gtk_notebook_set_homogeneous_tabs', 'E',
594 'gtk_notebook_set_page', 'E', # gtk_notebook_set_current_page() [==]
595 'gtk_notebook_set_tab_border', 'E',
596 'gtk_notebook_set_tab_hborder', 'E',
597 'gtk_notebook_set_tab_label_packing', 'E', # since 2.20
598 'gtk_notebook_set_tab_vborder', 'E',
599 'gtk_object_add_arg_type', 'E',
600 'gtk_object_data_force_id', 'E',
601 'gtk_object_data_try_key', 'E',
602 'GTK_OBJECT_FLOATING', 'E',
603 'gtk_object_get', 'E',
604 'gtk_object_get_data', 'E',
605 'gtk_object_get_data_by_id', 'E',
606 'gtk_object_get_user_data', 'E',
607 'gtk_object_new', 'E',
608 'gtk_object_ref', 'E',
609 'gtk_object_remove_data', 'E',
610 'gtk_object_remove_data_by_id', 'E',
611 'gtk_object_remove_no_notify', 'E',
612 'gtk_object_remove_no_notify_by_id', 'E',
613 'gtk_object_set', 'E',
614 'gtk_object_set_data', 'E',
615 'gtk_object_set_data_by_id', 'E',
616 'gtk_object_set_data_by_id_full', 'E',
617 'gtk_object_set_data_full', 'E',
618 'gtk_object_set_user_data', 'E',
619 'gtk_object_sink', 'E',
620 'GTK_OBJECT_TYPE', 'E', # G_OBJECT_TYPE
621 'GTK_OBJECT_TYPE_NAME', 'E', # G_OBJECT_TYPE_NAME
622 'gtk_object_unref', 'E',
623 'gtk_object_weakref', 'E',
624 'gtk_object_weakunref', 'E',
625 'gtk_old_editable_changed', 'E',
626 'gtk_old_editable_claim_selection', 'E',
627 'gtk_option_menu_get_history', 'E', # GtkComboBox ... (avail since 2.4/2.6/2.10/2.14)
628 'gtk_option_menu_get_menu', 'E',
629 'gtk_option_menu_new', 'E',
630 'gtk_option_menu_remove_menu', 'E',
631 'gtk_option_menu_set_history', 'E',
632 'gtk_option_menu_set_menu', 'E',
633 'gtk_paint_string', 'E',
634 'gtk_paned_gutter_size', 'E', # gtk_paned_set_gutter_size()
635 'gtk_paned_set_gutter_size', 'E', # "does nothing"
636 'gtk_pixmap_get', 'E', # GtkImage ...
637 'gtk_pixmap_new', 'E',
638 'gtk_pixmap_set', 'E',
639 'gtk_pixmap_set_build_insensitive', 'E',
640 'gtk_preview_draw_row', 'E',
641 'gtk_preview_get_cmap', 'E',
642 'gtk_preview_get_info', 'E',
643 'gtk_preview_get_visual', 'E',
644 'gtk_preview_new', 'E',
645 'gtk_preview_put', 'E',
646 'gtk_preview_reset', 'E',
647 'gtk_preview_set_color_cube', 'E',
648 'gtk_preview_set_dither', 'E',
649 'gtk_preview_set_expand', 'E',
650 'gtk_preview_set_gamma', 'E',
651 'gtk_preview_set_install_cmap', 'E',
652 'gtk_preview_set_reserved', 'E',
653 'gtk_preview_size', 'E',
654 'gtk_preview_uninit', 'E',
655 'gtk_progress_bar_new_with_adjustment', 'E',
656 'gtk_progress_bar_set_activity_blocks', 'E',
657 'gtk_progress_bar_set_activity_step', 'E',
658 'gtk_progress_bar_set_bar_style', 'E',
659 'gtk_progress_bar_set_discrete_blocks', 'E',
660 'gtk_progress_bar_update', 'E', # >>> "gtk_progress_set_value() or
661 # gtk_progress_set_percentage()"
662 ## Actually: GtkProgress is deprecated so the
663 ## right answer appears to be to use
664 ## gtk_progress_bar_set_fraction()
665 'gtk_progress_configure', 'E',
666 'gtk_progress_get_current_percentage', 'E',
667 'gtk_progress_get_current_text', 'E',
668 'gtk_progress_get_percentage_from_value', 'E',
669 'gtk_progress_get_text_from_value', 'E',
670 'gtk_progress_get_value', 'E',
671 'gtk_progress_set_activity_mode', 'E',
672 'gtk_progress_set_adjustment', 'E',
673 'gtk_progress_set_format_string', 'E',
674 'gtk_progress_set_percentage', 'E',
675 'gtk_progress_set_show_text', 'E',
676 'gtk_progress_set_text_alignment', 'E',
677 'gtk_progress_set_value', 'E',
678 'gtk_radio_button_group', 'E', # gtk_radio_button_get_group() [==]
679 'gtk_radio_menu_item_group', 'E',
680 'gtk_rc_add_class_style', 'E',
681 'gtk_rc_add_widget_class_style', 'E',
682 'gtk_rc_add_widget_name_style', 'E',
683 'gtk_rc_style_ref', 'E',
684 'gtk_rc_style_unref', 'E',
685 'gtk_recent_chooser_get_show_numbers', 'E',
686 'gtk_recent_chooser_set_show_numbers', 'E',
687 'gtk_recent_manager_get_for_screen', 'E',
688 'gtk_recent_manager_set_screen', 'E',
689 'GTK_RETLOC_BOOL', 'E',
690 'GTK_RETLOC_BOXED', 'E',
691 'GTK_RETLOC_CHAR', 'E',
692 'GTK_RETLOC_DOUBLE', 'E',
693 'GTK_RETLOC_ENUM', 'E',
694 'GTK_RETLOC_FLAGS', 'E',
695 'GTK_RETLOC_FLOAT', 'E',
696 'GTK_RETLOC_INT', 'E',
697 'GTK_RETLOC_LONG', 'E',
698 'GTK_RETLOC_OBJECT', 'E',
699 'GTK_RETLOC_POINTER', 'E',
700 'GTK_RETLOC_STRING', 'E',
701 'GTK_RETLOC_UCHAR', 'E',
702 'GTK_RETLOC_UINT', 'E',
703 'GTK_RETLOC_ULONG', 'E',
704 'gtk_selection_clear', 'E',
705 'gtk_signal_connect', 'E', # GSignal ...
706 'gtk_signal_connect_after', 'E',
707 'gtk_signal_connect_full', 'E',
708 'gtk_signal_connect_object', 'E',
709 'gtk_signal_connect_object_after', 'E',
710 'gtk_signal_connect_object_while_alive', 'E',
711 'gtk_signal_connect_while_alive', 'E',
712 'gtk_signal_default_marshaller', 'E',
713 'gtk_signal_disconnect', 'E',
714 'gtk_signal_disconnect_by_data', 'E',
715 'gtk_signal_disconnect_by_func', 'E',
716 'gtk_signal_emit', 'E',
717 'gtk_signal_emit_by_name', 'E',
718 'gtk_signal_emit_stop', 'E',
719 'gtk_signal_emit_stop_by_name', 'E',
720 'gtk_signal_emitv', 'E',
721 'gtk_signal_emitv_by_name', 'E',
722 'GTK_SIGNAL_FUNC', 'E',
723 'gtk_signal_handler_block', 'E',
724 'gtk_signal_handler_block_by_data', 'E',
725 'gtk_signal_handler_block_by_func', 'E',
726 'gtk_signal_handler_pending', 'E',
727 'gtk_signal_handler_pending_by_func', 'E',
728 'gtk_signal_handler_unblock', 'E',
729 'gtk_signal_handler_unblock_by_data', 'E',
730 'gtk_signal_handler_unblock_by_func', 'E',
731 'gtk_signal_lookup', 'E',
732 'gtk_signal_name', 'E',
733 'gtk_signal_new', 'E',
734 'gtk_signal_newv', 'E',
735 'GTK_SIGNAL_OFFSET', 'E',
736 'gtk_socket_steal', 'E',
737 'gtk_spin_button_get_value_as_float', 'E', # gtk_spin_button_get_value() [==]
738 'GTK_STRUCT_OFFSET', 'E',
739 'gtk_style_apply_default_pixmap', 'E',
740 'gtk_style_get_font', 'E',
741 'gtk_style_ref', 'E',
742 'gtk_style_set_font', 'E',
743 'gtk_style_unref', 'E', # g_object_unref() [==?]
744 'gtk_text_backward_delete', 'E',
745 'gtk_text_forward_delete', 'E',
746 'gtk_text_freeze', 'E',
747 'gtk_text_get_length', 'E',
748 'gtk_text_get_point', 'E',
749 'GTK_TEXT_INDEX', 'E',
750 'gtk_text_insert', 'E', # GtkTextView (GtkText "known to be buggy" !)
752 'gtk_text_set_adjustments', 'E',
753 'gtk_text_set_editable', 'E',
754 'gtk_text_set_line_wrap', 'E',
755 'gtk_text_set_point', 'E',
756 'gtk_text_set_word_wrap', 'E',
757 'gtk_text_thaw', 'E',
758 'gtk_timeout_add', 'E', # g_timeout_add()
759 'gtk_timeout_add_full', 'E',
760 'gtk_timeout_remove', 'E', # g_source_remove()
761 'gtk_tips_query_new', 'E',
762 'gtk_tips_query_set_caller', 'E',
763 'gtk_tips_query_set_labels', 'E',
764 'gtk_tips_query_start_query', 'E',
765 'gtk_tips_query_stop_query', 'E',
766 'gtk_toggle_button_set_state', 'E', # gtk_toggle_button_set_active [==]
767 'gtk_toolbar_append_element', 'E',
768 'gtk_toolbar_append_item', 'E',
769 'gtk_toolbar_append_space', 'E', # Use gtk_toolbar_insert() instead
770 'gtk_toolbar_append_widget', 'E', # ??
771 'gtk_toolbar_get_tooltips', 'E',
772 'gtk_toolbar_insert_element', 'E',
773 'gtk_toolbar_insert_item', 'E',
774 'gtk_toolbar_insert_space', 'E',
775 'gtk_toolbar_insert_stock', 'E',
776 'gtk_toolbar_insert_widget', 'E',
777 'gtk_toolbar_prepend_element', 'E',
778 'gtk_toolbar_prepend_item', 'E',
779 'gtk_toolbar_prepend_space', 'E',
780 'gtk_toolbar_prepend_widget', 'E',
781 'gtk_toolbar_remove_space', 'E',
782 'gtk_toolbar_set_tooltips', 'E',
783 'gtk_tree_append', 'E',
784 'gtk_tree_child_position', 'E',
785 'gtk_tree_clear_items', 'E',
786 'gtk_tree_insert', 'E',
787 'gtk_tree_item_collapse', 'E',
788 'gtk_tree_item_deselect', 'E',
789 'gtk_tree_item_expand', 'E',
790 'gtk_tree_item_new', 'E',
791 'gtk_tree_item_new_with_label', 'E',
792 'gtk_tree_item_remove_subtree', 'E',
793 'gtk_tree_item_select', 'E',
794 'gtk_tree_item_set_subtree', 'E',
795 'GTK_TREE_ITEM_SUBTREE', 'E',
796 'gtk_tree_model_get_iter_root', 'E',
798 'gtk_tree_path_new_root', 'E',
799 'gtk_tree_prepend', 'E',
800 'gtk_tree_remove_item', 'E',
801 'gtk_tree_remove_items', 'E',
802 'GTK_TREE_ROOT_TREE', 'E',
803 'gtk_tree_select_child', 'E',
804 'gtk_tree_select_item', 'E',
805 'GTK_TREE_SELECTION_OLD', 'E',
806 'gtk_tree_set_selection_mode', 'E',
807 'gtk_tree_set_view_lines', 'E',
808 'gtk_tree_set_view_mode', 'E',
809 'gtk_tree_unselect_child', 'E',
810 'gtk_tree_unselect_item', 'E',
811 'gtk_tree_view_tree_to_widget_coords', 'E',
812 'gtk_tree_view_widget_to_tree_coords', 'E',
813 'gtk_type_class', 'E', # g_type_class_peek() or g_type_class_ref()
814 'GTK_TYPE_CTREE_NODE', 'E',
815 'gtk_type_enum_find_value', 'E',
816 'gtk_type_enum_get_values', 'E',
817 'gtk_type_flags_find_value', 'E',
818 'gtk_type_flags_get_values', 'E',
819 'gtk_type_from_name', 'E',
820 'gtk_type_init', 'E',
821 'gtk_type_is_a', 'E',
822 'GTK_TYPE_IS_OBJECT', 'E',
823 'gtk_type_name', 'E',
825 'gtk_type_parent', 'E',
826 'gtk_type_unique', 'E',
827 'GTK_VALUE_BOOL', 'E',
828 'GTK_VALUE_BOXED', 'E',
829 'GTK_VALUE_CHAR', 'E',
830 'GTK_VALUE_DOUBLE', 'E',
831 'GTK_VALUE_ENUM', 'E',
832 'GTK_VALUE_FLAGS', 'E',
833 'GTK_VALUE_FLOAT', 'E',
834 'GTK_VALUE_INT', 'E',
835 'GTK_VALUE_LONG', 'E',
836 'GTK_VALUE_OBJECT', 'E',
837 'GTK_VALUE_POINTER', 'E',
838 'GTK_VALUE_SIGNAL', 'E',
839 'GTK_VALUE_STRING', 'E',
840 'GTK_VALUE_UCHAR', 'E',
841 'GTK_VALUE_UINT', 'E',
842 'GTK_VALUE_ULONG', 'E',
843 'gtk_vbutton_box_get_layout_default', 'E',
844 'gtk_vbutton_box_get_spacing_default', 'E',
845 'gtk_vbutton_box_set_layout_default', 'E',
846 'gtk_vbutton_box_set_spacing_default', 'E',
847 'gtk_widget_draw', 'E', # gtk_widget_queue_draw_area():
848 # "in general a better choice if you want
849 # to draw a region of a widget."
850 'gtk_widget_pop_visual', 'E',
851 'gtk_widget_push_visual', 'E',
852 'gtk_widget_queue_clear', 'E',
853 'gtk_widget_queue_clear_area', 'E',
854 'gtk_widget_ref', 'E', # g_object_ref() [==]
855 'gtk_widget_restore_default_style', 'E',
856 'gtk_widget_set', 'E', # g_object_set() [==]
857 'gtk_widget_set_default_visual', 'E',
858 'gtk_widget_set_rc_style', 'E',
859 'gtk_widget_set_uposition', 'E', # ?? (see GTK documentation)
860 'gtk_widget_set_usize', 'E', # gtk_widget_set_size_request()
861 'gtk_widget_set_visual', 'E',
862 'gtk_widget_unref', 'E',
863 'gtk_window_position', 'E',
864 'gtk_window_set_policy', 'E', # >>? gtk_window_set_resizable()
866 ## Deprecated for GTK+ versions greater than 2.4
867 ## Note that entries marked with 'W' are currently being used by Wireshark
868 ## Those marked with 'E' are not being used by Wireshark
870 ## Deprecated as of GTK+ 2.12 but to be replaced only when Wireshark requires GTK+ 2.12 or later
871 ## (or: use conditional code based upon the GTK version).
872 'gtk_tooltips_data_get', 'E', # new API: GtkToolTip (avail since 2.12) ...
873 'gtk_tooltips_disable', 'E',
874 'gtk_tooltips_enable', 'E',
875 'gtk_tooltips_force_window', 'E',
876 'gtk_tooltips_get_info_from_tip_window', 'E',
877 ## 'gtk_tooltips_new', 'W',
878 'gtk_tooltips_set_delay', 'E',
879 ## 'gtk_tooltips_set_tip', 'W',
880 ## 'gtk_tool_item_set_tooltip', 'W', # gtk_tool_item_set_tooltip_text() (avail since 2.12)
882 ## Deprecated as of GTK+ 2.16 but to be replaced only when Wireshark requires GTK+ 2.16 or later
883 ## (or: use conditional code based upon the GTK version).
884 'gtk_scale_button_get_orientation', 'E', # gtk_orientable_get_orientation() (avail since 2.16)
885 'gtk_scale_button_set_orientation', 'E', # gtk_orientable_set_orientation() (avail since 2.16)
886 'gtk_toolbar_get_orientation', 'E', # gtk_orientable_get_orientation() (avail since 2.16)
887 ## 'gtk_toolbar_set_orientation', 'W', # gtk_orientable_set_orientation() (avail since 2.16)
888 'gtk_status_icon_set_tooltip', 'E', # gtk_status_icon_set_tooltip_text() (avail since 2.16)
889 'gtk_widget_get_action', 'E', # gtk_activatable_get_related_action() (avail since 2.16)
891 ## Deprecated as of GTK+ 2.18 but to be replaced only when Wireshark requires GTK+ 2.12 or later
892 ## (or: use conditional code based upon the GTK version).
893 'gtk_cell_view_get_cell_renderers', 'E', # gtk_cell_layout_get_cells () (avail since 2.12)
894 ## 'gtk_tree_view_column_get_cell_renderers', 'W', # gtk_cell_layout_get_cells () (avail since 2.12)
896 ## Deprecated as of GTK+ 2.20 but to be replaced only when Wireshark requires GTK+ 2.18 or later
897 ## (or: use conditional code based upon the GTK version).
898 'GTK_WIDGET_APP_PAINTABLE', 'E', # gtk_widget_get_app_paintable() (avail since 2.18)
899 'GTK_WIDGET_CAN_DEFAULT', 'E', # gtk_widget_getcan_default() (avail since 2.18)
900 'GTK_WIDGET_CAN_FOCUS', 'E', # gtk_widget_getcan_focus() (avail since 2.18)
901 'GTK_WIDGET_COMPOSITE_CHILD', 'E', # gtk_widget_getcomposite_child() (avail since 2.18)
902 'GTK_WIDGET_DOUBLE_BUFFERED', 'E', # gtk_widget_getdouble_buffered() (avail since 2.18)
903 'GTK_WIDGET_DRAWABLE', 'E', # gtk_widget_getdrawable() (avail since 2.18)
904 'GTK_WIDGET_FLAGS', 'E', # gtk_widget_getflags() (avail since 2.18)
905 'GTK_WIDGET_HAS_DEFAULT', 'E', # gtk_widget_gethas_default() (avail since 2.18)
906 'GTK_WIDGET_HAS_FOCUS', 'E', # gtk_widget_gethas_focus() (avail since 2.18)
907 'GTK_WIDGET_HAS_GRAB', 'E', # gtk_widget_gethas_grab() (avail since 2.18)
908 'GTK_WIDGET_IS_SENSITIVE', 'E', # gtk_widget_getis_sensitive() (avail since 2.18)
909 'GTK_WIDGET_MAPPED', 'E', # gtk_widget_getmapped() (avail since 2.18)
910 'GTK_WIDGET_NO_WINDOW', 'W', # gtk_widget_getno_window() (avail since 2.18)
911 'GTK_WIDGET_PARENT_SENSITIVE', 'E', # gtk_widget_getparent_sensitive() (avail since 2.18)
912 'GTK_WIDGET_RC_STYLE', 'E', # gtk_widget_getrc_style() (avail since 2.18)
913 'GTK_WIDGET_REALIZED', 'W', # gtk_widget_getrealized() (avail since 2.18)
914 'GTK_WIDGET_RECEIVES_DEFAULT', 'E', # gtk_widget_getreceives_default() (avail since 2.18)
915 'GTK_WIDGET_SAVED_STATE', 'E', # gtk_widget_getsaved_state() (avail since 2.18)
916 'GTK_WIDGET_SENSITIVE', 'W', # gtk_widget_getsensitive() (avail since 2.18)
917 'GTK_WIDGET_STATE', 'W', # gtk_widget_getstate() (avail since 2.18)
918 'GTK_WIDGET_TOPLEVEL', 'E', # gtk_widget_gettoplevel() (avail since 2.18)
919 'GTK_WIDGET_TYPE', 'E', # gtk_widget_gettype() (avail since 2.18)
920 'GTK_WIDGET_VISIBLE', 'W', # gtk_widget_getvisible() (avail since 2.18)
923 @{$APIs{'deprecated-gtk'}->{'functions'}} = grep {$deprecatedGtkFunctions{$_} eq 'E'} keys %deprecatedGtkFunctions;
924 @{$APIs{'deprecated-gtk-todo'}->{'functions'}} = grep {$deprecatedGtkFunctions{$_} eq 'W'} keys %deprecatedGtkFunctions;
928 # Given a ref to a hash containing "functions" and "functions_count" entries:
929 # Determine if the any of the list of APIs contained in the array referenced by "functions"
930 # exists in the file.
931 # For each API which appears in the file:
932 # Push the API onto the provided list;
933 # Add the number of times the API appears in the file to the total count
934 # for the API (stored as the value of the API key in the hash referenced by "function_counts").
936 sub findAPIinFile($$$)
938 my ($groupHashRef, $fileContentsRef, $foundAPIsRef) = @_;
940 for my $api ( @{$groupHashRef->{functions}} )
943 while (${$fileContentsRef} =~ m/ \W $api \W* \( /gx)
948 push @{$foundAPIsRef}, $api;
949 $groupHashRef->{function_counts}->{$api} += 1;
954 # The below Regexp are based on those from:
955 # http://aspn.activestate.com/ASPN/Cookbook/Rx/Recipe/59811
956 # They are in the public domain.
958 # 1. A complicated regex which matches C-style comments.
959 my $CComment = qr{ / [*] [^*]* [*]+ (?: [^/*] [^*]* [*]+ )* / }x;
961 # 1.a A regex that matches C++-style comments.
962 #my $CppComment = qr{ // (.*?) \n }x;
964 # 2. A regex which matches double-quoted strings.
965 # ?s added so that strings containing a 'line continuation'
966 # ( \ followed by a new-line) will match.
967 my $DoubleQuotedStr = qr{ (?: ["] (?s: \\. | [^\"\\])* ["]) }x;
969 # 3. A regex which matches single-quoted strings.
970 my $SingleQuotedStr = qr{ (?: \' (?: \\. | [^\'\\])* [']) }x;
972 # 4. Now combine 1 through 3 to produce a regex which
973 # matches _either_ double or single quoted strings
974 # OR comments. We surround the comment-matching
975 # regex in capturing parenthesis to store the contents
976 # of the comment in $1.
977 # my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)|($CppComment)};
979 # 4. Wireshark is strictly a C program so don't take out C++ style comments
980 # since they shouldn't be there anyway...
981 # Also: capturing the comment isn't necessary.
982 my $commentAndStringRegex = qr{ (?: $DoubleQuotedStr | $SingleQuotedStr | $CComment) }x;
984 #### Regex for use when searching for value-string definitions
985 my $StaticRegex = qr/ static \s+ /xs;
986 my $ConstRegex = qr/ const \s+ /xs;
987 my $Static_andor_ConstRegex = qr/ (?: $StaticRegex $ConstRegex | $StaticRegex | $ConstRegex) /xs;
988 my $ValueStringRegex = qr/ $Static_andor_ConstRegex value_string \ + [^;*]+ = [^;]+ [{] [^;]+ ; /xs;
994 # The default list, which can be expanded.
995 my @apiGroups = qw(prohibited deprecated);
996 my @apiSummaryGroups = ();
997 my $check_value_string_array_null_termination = 1; # default: enabled
998 my $machine_readable_output = 0; # default: disabled
1001 my $result = GetOptions(
1002 'group=s' => \@apiGroups,
1003 'summary-group=s' => \@apiSummaryGroups,
1004 'check-value-string-array-null-termination!' => \$check_value_string_array_null_termination,
1005 'Machine-readable' => \$machine_readable_output,
1006 'debug' => \$debug_flag
1009 print "Usage: checkAPIs.pl [-M] [-g group1] [-g group2] ... [-s group1] [-s group2] ... [--nocheck-value-string-array-null-termination] file1 file2 ..\n";
1010 print " -g <group>: Check input files for use of APIs in <group> (in addition to the default groups)\n";
1011 print " -s <group>: Output summary (count) for each API in <group> (-g <group> also req'd)\n";
1012 print " -M: Generate output for -g in 'machine-readable' format\n";
1014 print " Default Groups[-g]: ", join (", ", sort @apiGroups), "\n";
1015 print " Available Groups: ", join (", ", sort keys %APIs), "\n";
1019 # Add a 'function_count' anonymous hash to each of the 'apiGroup' entries in the %APIs hash.
1020 for my $apiGroup (keys %APIs) {
1021 my @functions = @{$APIs{$apiGroup}{functions}};
1023 $APIs{$apiGroup}->{function_counts} = {};
1024 @{$APIs{$apiGroup}->{function_counts}}{@functions} = (); # Add fcn names as keys to the anonymous hash
1028 # Read through the files; do various checks
1029 while ($_ = $ARGV[0])
1033 my $fileContents = '';
1036 die "No such file: \"$filename\"" if (! -e $filename);
1038 # delete leading './'
1039 $filename =~ s{ ^ \. / } {}xo;
1041 # Read in the file (ouch, but it's easier that way)
1042 open(FC, $filename) || die("Couldn't open $filename");
1043 while (<FC>) { $fileContents .= $_; }
1046 if ($fileContents =~ m{ [\x80-\xFF] }xo)
1048 print STDERR "Error: Found non-ASCII characters in " .$filename."\n";
1052 if ($fileContents =~ m{ %ll }xo)
1054 # use G_GINT64_MODIFIER instead of ll
1055 print STDERR "Error: Found %ll in " .$filename."\n";
1058 if ($fileContents =~ m{ %hh }xo)
1060 # %hh is C99 and Windows doesn't like it:
1061 # http://connect.microsoft.com/VisualStudio/feedback/details/416843/sscanf-cannot-not-handle-hhd-format
1062 # Need to use temporary variables instead.
1063 print STDERR "Error: Found %hh in " .$filename."\n";
1067 if (! ($fileContents =~ m{ \$Id .* \$ }xo))
1069 print STDERR "Warning: ".$filename." does not have an SVN Id tag.\n";
1072 # Remove all the C-comments and strings
1073 $fileContents =~ s {$commentAndStringRegex} []xog;
1075 if ($fileContents =~ m{ // }xo)
1077 print STDERR "Error: Found C++ style comments in " .$filename."\n";
1081 # Brute force check for value_string arrays which are missing {0, NULL} as the final (terminating) array entry
1082 if ($check_value_string_array_null_termination) {
1083 # Assumption: definition is of form (pseudo-Regex):
1084 # " (static const|static|const) value_string .+ = { .+ ;" (possibly over multiple lines)
1085 while ($fileContents =~ / ( $ValueStringRegex ) /xsog) {
1086 # value_string array definition found; check if NULL terminated
1087 my $vs = my $vsx = $1;
1089 $vsx =~ / ( .+ value_string [^=]+ ) = /xo;
1090 printf STDERR "==> %-35.35s: %s\n", $filename, $1;
1091 printf STDERR "%s\n", $vs;
1093 $vs =~ s{ \s } {}xg;
1094 # README.developer says
1095 # "Don't put a comma after the last tuple of an initializer of an array"
1096 # However: since this usage is present in some number of cases, we'll allow for now
1097 if ($vs !~ / , NULL [}] ,? [}] ; $/xo) {
1098 $vsx =~ /( value_string [^=]+ ) = /xo;
1099 printf STDERR "Error: %-35.35s: {0, NULL} is required as the last value_string array entry: %s\n", $filename, $1;
1102 if ($vs !~ / (static)? const value_string /xo) {
1103 $vsx =~ /( value_string [^=]+ ) = /xo;
1104 printf STDERR "Error: %-35.35s: Missing 'const': %s\n", $filename, $1;
1110 # Check and count APIs
1111 for my $apiGroup (@apiGroups) {
1112 my $pfx = "Warning";
1115 findAPIinFile($APIs{$apiGroup}, \$fileContents, \@foundAPIs);
1117 if ($APIs{$apiGroup}->{count_errors}) {
1118 # the use of "prohibited" APIs is an error, increment the error count
1119 $errorCount += @foundAPIs;
1123 if (@foundAPIs && ! $machine_readable_output) {
1124 print STDERR $pfx . ": Found " . $apiGroup . " APIs in ".$filename.": ".join(',', @foundAPIs)."\n"
1126 if (@foundAPIs && $machine_readable_output) {
1127 for my $api (@foundAPIs) {
1128 printf STDERR "%-8.8s %-20.20s %-30.30s %-45.45s\n", $pfx, $apiGroup, $filename, $api;
1134 # Summary: Print Use Counts of each API in each requested summary group
1136 for my $apiGroup (@apiSummaryGroups) {
1137 printf "\n\nUse Counts\n";
1138 for my $api (sort {"\L$a" cmp "\L$b"} (keys %{$APIs{$apiGroup}->{function_counts}} )) {
1139 printf "%-20.20s %5d %-40.40s\n", $apiGroup . ':', $APIs{$apiGroup}{function_counts}{$api}, $api;