From: Duncan C. <dun...@us...> - 2004-07-29 14:33:27
|
Update of /cvsroot/gtk2hs/gtk2hs/tools/apicoverage In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16344/tools/apicoverage Added Files: Exclude.hs Makefile README gtk.ignore Log Message: new tool to check on our coverage of the gtk api. See README for details. --- NEW FILE: README --- The tools in this directory are to help investigate gtk2hs's coverage of the gtk API. You should modify the Makefile to set which version of gtk you'd like to check aginst. Running 'make' will then download the tarball from the gtk website and extract the gtk.def file which contains a complete list of the exported gtk functions. It also scans all the files in the gtk directory for calls to gtk APIs. It filters the list of gtk APIs to get rid of deprecated, internal or other functions we don't care about. So what you want to do is $ make to get a summary and then $ diff gtk.def.filtered gtk.coverage to get a list of what is currently implemented vs what is not. If something should not be implemented you can exclude it from the list by modifying the gtk.ignore file. You can also put api.ignore files in any directory under gtk/ and they will be used too. For excluding individual functions it's probably better to use a local api.ignore file, to stop the main gtk.ignore file becoming unmanagebly large. The central one should be for excluding entire sections of the gtk api and general stuff. The syntax of these files is as follows: * empty lines or lines beginning with # are ignored * lines like: exclude gtk_some_group_of_functions give an instruction to ignore functions with a name that matches the regex. Note that functions will be excluded if the regex matches any part of the function name, so saying 'gtk_text' will exclude all functions with that prefix. Standard posix regex syntax applies so you can use ^ and $ to anchor the regex if you need, eg '_get_type$' will only match things things ending in '_get_type' * lines like: do not exclude gtk_some_function can be used where using 'exclude' has excluded too much and you need some exceptions. eg to exclude gtk_progress but not gtk_progress_box * finally: always exclude _gtk_type$ can be used where you really really want to exclude something even if a 'do not exclude' would have caused it not to be excluded. This is mostly only useful for the above example and a couple similar ones. --- NEW FILE: Makefile --- # system to help check gtk2hs's api coverage # which vesion of gtk+ to compare against GTK_MAJOR_VERSION = 2 GTK_MINOR_VERSION = 4 GTK_MICRO_VERSION = 4 GTK_VERSION = $(GTK_MAJOR_VERSION).$(GTK_MINOR_VERSION).$(GTK_MICRO_VERSION) main: stats tars/gtk+-$(GTK_VERSION).tar.bz2 : wget ftp://ftp.gtk.org/pub/gtk/v2.$(GTK_MINOR_VERSION)/gtk+-$(GTK_VERSION).tar.bz2 \ --directory-prefix=tars gtk.def : tars/gtk+-$(GTK_VERSION).tar.bz2 tar --file tars/gtk+-$(GTK_VERSION).tar.bz2 -j --get gtk+-$(GTK_VERSION)/gtk/gtk.def -O > gtk.def sed -i 's:\(\t\|EXPORTS\)::' gtk.def GTK_CHS_FILES = $(shell find ../../gtk -name '*.chs') gtk.coverage : $(GTK_CHS_FILES) grep -h 'foreign import ccall \(unsafe \)\?" \?&\?.*"' `find ../../gtk -name '*.hs'` | \ sed 's:foreign import ccall \(unsafe \)\?" \?&\?\(.*\)".*:\2:' | \ sort -u | grep '^gtk_' | grep --invert-match '_get_type$$' > gtk.coverage # We can have (optional) api.ignore files in the gtk directories to have a # local place to record functions we don't want to bind, that'd stop the # central one getting huge. GTK_IGNORE_FILES = $(shell find ../../gtk -name 'api.ignore') gtk.ignore.combined : gtk.ignore $(GTK_IGNORE_FILES) cat $^ > gtk.ignore.combined gtk.def.filtered : gtk.def exclude gtk.ignore.combined ./exclude gtk.ignore.combined < gtk.def > gtk.def.filtered exclude : Exclude.hs ghc --make Exclude.hs -o exclude clean : rm -f Exclude.hi Exclude.o exclude rm -f gtk.coverage gtk.def.filtered gtk.def gtk.ignore.combined gtk_total=$(shell wc -l < gtk.def.filtered) gtk2hs_total=$(shell wc -l < gtk.coverage) stats : gtk.def.filtered gtk.coverage @echo "**** gtk2hs API coverage report (for gtk-$(GTK_VERSION)) ****" @echo " total gtk functions :" $(gtk_total) @echo " total gtk2hs functions :" $(gtk2hs_total) @echo " difference :" `echo $(gtk_total) - $(gtk2hs_total) | bc` @echo; echo "run 'diff gtk.def.filtered gtk.coverage' to see in detail" debug: @echo GTK_IGNORE_FILES = $(GTK_IGNORE_FILES) --- NEW FILE: Exclude.hs --- module Main (main) where import Char (isSpace) import Maybe (catMaybes, isJust) import List (isPrefixOf, intersperse) import System (getArgs) import Text.Regex main = do [filterFileName] <- getArgs filterFile <- readFile filterFileName let match = matcher (parseFilterFile filterFile) interact (unlines . filter match . lines) data FilterSpec = Exclude String | NotExclude String -- override Exclude but not AlwaysExclude | AlwaysExclude String parseFilterFile :: String -> [FilterSpec] parseFilterFile = catMaybes . map parseLine . lines where parseLine [] = Nothing parseLine ('#':_) = Nothing parseLine line | "exclude " `isPrefixOf` line = Just $ Exclude $ trim $ drop 8 line | "do not exclude " `isPrefixOf` line = Just $ NotExclude $ trim $ drop 15 line | "always exclude " `isPrefixOf` line = Just $ AlwaysExclude $ trim $ drop 15 line parseLine line = error $ "cannot parse line: " ++ line trim = takeWhile (not . isSpace) . dropWhile isSpace matcher :: [FilterSpec] -> (String -> Bool) matcher spec = match where excludeRegex = mkRegex $ concat $ intersperse "|" [ regex | Exclude regex <- spec ] noExcludeRegex = mkRegex $ concat $ intersperse "|" [ regex | NotExclude regex <- spec ] alwaysExcludeRegex = mkRegex $ concat $ intersperse "|" [ regex | AlwaysExclude regex <- spec ] match line = not $ ((isJust $ matchRegex excludeRegex line) && (not $ isJust $ matchRegex noExcludeRegex line)) || (isJust $ matchRegex alwaysExcludeRegex line) --- NEW FILE: gtk.ignore --- # all functions matching these regexps are ignored from gtk.def #deprecated exclude gtk_object do not exclude gtk_object_sink exclude gtk_ctree exclude gtk_clist exclude gtk_tree exclude gtk_list do not exclude gtk_list_store do not exclude gtk_tree_store do not exclude gtk_tree_view do not exclude gtk_tree_model do not exclude gtk_tree_sortable do not exclude gtk_tree_selection do not exclude gtk_tree_row do not exclude gtk_tree_path exclude gtk_pixmap exclude gtk_item_factory exclude gtk_old_editable exclude gtk_preview exclude gtk_progress do not exclude gtk_progress_bar_new do not exclude gtk_progress_bar_pulse do not exclude gtk_progress_bar_set_text do not exclude gtk_progress_bar_set_fraction do not exclude gtk_progress_bar_set_pulse_step do not exclude gtk_progress_bar_set_orientation do not exclude gtk_progress_bar_get_text do not exclude gtk_progress_bar_get_fraction do not exclude gtk_progress_bar_get_pulse_step do not exclude gtk_progress_bar_get_orientation exclude gtk_text do not exclude gtk_text_iter do not exclude gtk_text_mark do not exclude gtk_text_buffer do not exclude gtk_text_tag do not exclude gtk_text_tag_table do not exclude gtk_text_view exclude gtk_tips_query exclude gtk_accel_group_ref exclude gtk_accel_group_unref exclude gtk_idle exclude gtk_timeout exclude gtk_input exclude gtk_exit exclude gtk_type exclude gtk_color_selection_set_update_policy #deprecated as of 2.4 exclude gtk_combo do not exclude gtk_combo_box exclude gtk_option_menu #special purpose features (hangovers in gtk from the GIMP) exclude gtk_curve exclude gtk_gamma_curve exclude gtk_ruler exclude gtk_hruler exclude gtk_vruler #low level exclude gtk_marshal exclude gtk_false exclude gtk_true exclude gtk_.*_version exclude gtk_requisition #for gtk extensions & widget implementations exclude gtk_draw do not exclude gtk_drawing exclude gtk_style exclude gtk_paint exclude gtk_file_info exclude gtk_file_system exclude gtk_file_folder exclude gtk_im exclude gtk_invisible exclude gtk_widget_realize exclude gtk_widget_unrealize #sometimes there are several ways of doing the same thing #so lets ignore the other ways of doing it exclude gtk_init do not exclude gtk_init_check$ #dont think we need these ? TODO check this exclude gtk_gc exclude gtk_key_snooper exclude gtk_rc #appear to be internal, they're not well documented exclude gtk_binding exclude gtk_debug #stuff that we do not call directly, but instead simulate #usually because the function is varargs exclude gtk_file_chooser_dialog_new #these are sometimes bound if necessary but otherwise we can ignore them always exclude _get_type$ always exclude _valist$ always exclude _newv$ always exclude _copy$ always exclude _free$ exclude _ref$ exclude _unref$ |