├── .github └── FUNDING.yml ├── Makefile ├── modules └── Internals │ ├── Scripts │ └── Sections.js │ ├── Styles │ ├── List.css │ ├── Test.css │ └── Report.css │ └── RegTests.pm ├── README.md ├── INSTALL ├── Makefile.pl ├── doc ├── index.html ├── Xml-Descriptor.html ├── Specialized-Type.html └── Changelog.html └── LICENSE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: LINUXABI 4 | custom: https://abi-laboratory.pro/?view=donate 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | prefix ?= /usr 2 | 3 | .PHONY: all 4 | 5 | all: 6 | echo "Nothing to build." 7 | 8 | install: 9 | perl Makefile.pl -install -prefix "$(prefix)" 10 | 11 | uninstall: 12 | perl Makefile.pl -remove -prefix "$(prefix)" 13 | 14 | clean: 15 | echo "Nothing to clean up." 16 | -------------------------------------------------------------------------------- /modules/Internals/Scripts/Sections.js: -------------------------------------------------------------------------------- 1 | function showContent(header, id) 2 | { 3 | e = document.getElementById(id); 4 | if(e.style.display == 'none') 5 | { 6 | e.style.display = 'block'; 7 | e.style.visibility = 'visible'; 8 | header.innerHTML = header.innerHTML.replace(/\[[^0-9 ]\]/gi,"[−]"); 9 | } 10 | else 11 | { 12 | e.style.display = 'none'; 13 | e.style.visibility = 'hidden'; 14 | header.innerHTML = header.innerHTML.replace(/\[[^0-9 ]\]/gi,"[+]"); 15 | } 16 | } -------------------------------------------------------------------------------- /modules/Internals/Styles/List.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family:Arial; 3 | background-color:White; 4 | color:Black; 5 | } 6 | hr { 7 | color:Black; 8 | background-color:Black; 9 | height:1px; 10 | border:0; 11 | } 12 | h1 { 13 | margin-bottom:0px; 14 | padding-bottom:0px; 15 | font-size:1.625em; 16 | } 17 | h2 { 18 | margin-bottom:0px; 19 | padding-bottom:0px; 20 | font-size:1.25em; 21 | } 22 | span.int { 23 | font-weight:bold; 24 | cursor:pointer; 25 | margin-left:7px; 26 | font-family:Arial; 27 | color:#003E69; 28 | } 29 | span.sym_p { 30 | font-weight:normal; 31 | } 32 | span:hover.int { 33 | color:#336699; 34 | } 35 | span.header { 36 | color:#cc3300; 37 | font-size:0.875em; 38 | font-weight:bold; 39 | } 40 | span.ns { 41 | color:#408080; 42 | font-size:0.94em; 43 | } 44 | span.lib_name { 45 | color:Green; 46 | font-size:0.875em; 47 | font-weight:bold; 48 | } 49 | span.libgroup { 50 | color:Black; 51 | font-size:0.875em; 52 | font-family:Arial; 53 | font-weight:bold; 54 | } 55 | span.nowrap { 56 | white-space:nowrap; 57 | } 58 | span.attr { 59 | color:#333333; 60 | font-weight:100; 61 | } 62 | span.color_p { 63 | font-style:italic; 64 | color:Brown; 65 | } 66 | span.param { 67 | font-style:italic; 68 | } 69 | span.focus_p { 70 | font-style:italic; 71 | color:Red; 72 | } 73 | a.link { 74 | text-decoration:none; 75 | } 76 | .footer { 77 | font-size:0.75em; 78 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | API Sanity Checker 1.98.8 2 | ========================= 3 | 4 | API Sanity Checker — an automatic generator of basic unit tests for a C/C++ library API. 5 | 6 | Contents 7 | -------- 8 | 9 | 1. [ About ](#about) 10 | 2. [ Install ](#install) 11 | 3. [ Usage ](#usage) 12 | 4. [ Test suite ](#test-suite) 13 | 14 | About 15 | ----- 16 | 17 | The tool is able to generate reasonable (in most, but unfortunately not all, cases) input data for parameters and compose simple ("sanity" or "shallow"-quality) test cases for every function in the API through the analysis of declarations in header files. 18 | 19 | The quality of generated tests allows to check absence of critical errors in simple use cases. The tool is able to build and execute generated tests and detect crashes (segfaults), all kinds of emitted signals, non-zero program return code and program hanging. 20 | 21 | The tool is developed by Andrey Ponomarenko. 22 | 23 | Install 24 | ------- 25 | 26 | sudo make install prefix=/usr 27 | 28 | ###### Requires 29 | 30 | * ABI Compliance Checker 1.99.24 or newer: https://github.com/lvc/abi-compliance-checker 31 | * Perl 5 32 | * G++ 33 | * GNU Binutils 34 | * Ctags 35 | 36 | Usage 37 | ----- 38 | 39 | api-sanity-checker -lib NAME -d VERSION.xml -gen -build -run 40 | 41 | `VERSION.xml` is XML-descriptor: 42 | 43 | 44 | 1.0 45 | 46 | 47 | 48 | /path/to/headers/ 49 | 50 | 51 | 52 | /path/to/libraries/ 53 | 54 | 55 | ###### Adv. usage 56 | 57 | For advanced usage, see `doc/index.html` or output of `-help` option. 58 | 59 | Test suite 60 | ---------- 61 | 62 | A small test to check that the tool works properly in your environment: 63 | 64 | api-sanity-checker -test 65 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2009-2011 Institute for System Programming, RAS 3 | Copyright (C) 2011-2016 Andrey Ponomarenko's ABI Laboratory 4 | All rights reserved. 5 | 6 | 7 | RELEASE INFORMATION 8 | 9 | Project: API Sanity Checker 10 | Version: 1.98.8 11 | Date: 2016-09-29 12 | 13 | 14 | This file explains how to install and setup environment 15 | for the tool in your computer. 16 | 17 | 18 | Content: 19 | 20 | 1. Requirements for Linux and FreeBSD 21 | 2. Requirements for Mac OS X 22 | 3. Requirements for MS Windows 23 | 4. Configuring and Installing 24 | 5. Running the Tool 25 | 26 | 27 | 1. REQUIREMENTS FOR LINUX AND FREEBSD 28 | ===================================== 29 | 30 | 1. ABI Compliance Checker (1.99.24 or newer) 31 | 2. G++ (3.0-4.7, 4.8.3, 4.9 or newer) 32 | 3. GNU Binutils (c++filt, readelf, objdump) 33 | 4. Perl 5 (5.8 or newer) 34 | 5. Ctags (5.8 or newer) 35 | 36 | 37 | 38 | 2. REQUIREMENTS FOR MAC OS X 39 | ============================ 40 | 41 | 1. ABI Compliance Checker (1.99.24 or newer) 42 | 2. Xcode (gcc, c++filt, nm) 43 | 3. Ctags (5.8 or newer) 44 | 45 | 46 | 47 | 3. REQUIREMENTS FOR MS WINDOWS 48 | ============================== 49 | 50 | 1. ABI Compliance Checker (1.99.24 or newer) 51 | 2. MinGW (3.0-4.7, 4.8.3, 4.9 or newer) 52 | 3. MS Visual C++ (dumpbin, undname, cl) 53 | 4. Active Perl 5 (5.8 or newer) 54 | 5. Ctags (5.8 or newer) 55 | 56 | 3.1 Setup environment 57 | 58 | 1. Add locations of necessary tools to the PATH environment variable 59 | 2. Run vcvars64.bat script (C:\Microsoft Visual Studio 9.0\VC\bin\) 60 | 61 | 62 | 63 | 4. CONFIGURING AND INSTALLING 64 | =================================================== 65 | 66 | This command will install an api-sanity-checker program in the 67 | PREFIX/bin system directory: 68 | 69 | sudo make install prefix=PREFIX [/usr, /usr/local, ...] 70 | 71 | 4.1 Remove 72 | 73 | sudo make uninstall prefix=PREFIX 74 | 75 | 76 | 77 | 5. RUNNING THE TOOL 78 | =================== 79 | 80 | 1. Create an XML-descriptor 81 | for your library (VERSION.xml): 82 | 83 | 84 | 1.0 85 | 86 | 87 | 88 | /path1/to/header(s)/ 89 | /path2/to/header(s)/ 90 | ... 91 | 92 | 93 | 94 | /path1/to/library(ies)/ 95 | /path2/to/library(ies)/ 96 | ... 97 | 98 | 99 | 2. api-sanity-checker -lib NAME -d VERSION.xml -gen -build -run 100 | 3. For advanced usage, see doc/index.html or --help option 101 | 102 | 103 | 104 | Enjoy! 105 | -------------------------------------------------------------------------------- /modules/Internals/Styles/Test.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family:Arial; 3 | background-color:White; 4 | color:Black; 5 | } 6 | h1 { 7 | margin-bottom:0px; 8 | padding-bottom:0px; 9 | font-size:1.625em; 10 | } 11 | h2 { 12 | margin-bottom:0px; 13 | padding-bottom:0px; 14 | font-size:1.25em; 15 | } 16 | span.int { 17 | font-weight:bold; 18 | color:#003E69; 19 | } 20 | span.sym_p { 21 | font-weight:normal; 22 | } 23 | hr { 24 | color:Black; 25 | background-color:Black; 26 | height:1px; 27 | border:0; 28 | } 29 | span.comm { 30 | color:#888888; 31 | } 32 | span.str { 33 | color:#FF00FF; 34 | } 35 | span.var { 36 | color:Black; 37 | font-style:italic; 38 | } 39 | span.prepr { 40 | color:Green; 41 | } 42 | span.type { 43 | color:Brown; 44 | } 45 | span.keyw { 46 | font-weight:bold; 47 | } 48 | span.num { 49 | color:Blue; 50 | } 51 | span.targ { 52 | color:Red; 53 | } 54 | td.targ { 55 | background-color:#FFD1D1 56 | } 57 | span.nowrap { 58 | white-space:nowrap; 59 | } 60 | span.attr { 61 | color:#333333; 62 | font-weight:100; 63 | } 64 | span.color_p { 65 | font-style:italic; 66 | color:Brown; 67 | } 68 | span.param { 69 | font-style:italic; 70 | } 71 | span.focus_p { 72 | font-style:italic; 73 | color:Red; 74 | } 75 | span.yellow { 76 | background-color:#FFFFD6; 77 | } 78 | pre { 79 | padding: 0; 80 | margin: 0; 81 | word-wrap:break-word; 82 | white-space: pre-wrap; 83 | } 84 | table.test_view { 85 | cursor:text; 86 | margin-top:7px; 87 | font-family:Monaco, Consolas, 'DejaVu Sans Mono', 'Droid Sans Mono', Monospace; 88 | font-size:14px; 89 | padding:0px; 90 | border:1px solid Black; 91 | color:#444444; 92 | background-color:White; 93 | overflow:auto; 94 | } 95 | table.test_view th { 96 | background-color:White; 97 | padding-right:3px; 98 | padding-left:3px; 99 | text-align:right; 100 | font-weight:100; 101 | padding:0px 4px 0px 10px; 102 | vertical-align:top; 103 | 104 | -moz-user-select:none; 105 | -o-user-select:none; 106 | -webkit-user-select:none; 107 | -khtml-user-select:none; 108 | -ms-user-select:none; 109 | user-select:none; 110 | } 111 | table.test_view td { 112 | padding-left:15px; 113 | text-align:left; 114 | word-wrap:break-word; 115 | max-width:900px; 116 | padding:0px 15px 0px 15px; 117 | } 118 | table.summary { 119 | border-collapse:collapse; 120 | border:1px outset black; 121 | } 122 | table.summary th { 123 | background-color:#eeeeee; 124 | font-weight:100; 125 | text-align:left; 126 | font-size:0.94em; 127 | white-space:nowrap; 128 | border:1px inset black; 129 | padding: 1px 2px 1px 2px; 130 | } 131 | table.summary td { 132 | text-align:left; 133 | white-space:nowrap; 134 | border:1px inset black; 135 | padding: 1px 2px 1px 2px; 136 | } 137 | .footer { 138 | font-size:0.75em; 139 | } -------------------------------------------------------------------------------- /modules/Internals/Styles/Report.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family:Arial; 3 | background-color:White; 4 | color:Black; 5 | } 6 | hr { 7 | color:Black; 8 | background-color:Black; 9 | height:1px; 10 | border:0; 11 | } 12 | h1 { 13 | margin-bottom:0px; 14 | padding-bottom:0px; 15 | font-size:1.625em; 16 | } 17 | h2 { 18 | margin-bottom:0px; 19 | padding-bottom:0px; 20 | font-size:1.25em; 21 | } 22 | span.section { 23 | white-space:normal; 24 | font-weight:bold; 25 | cursor:pointer; 26 | margin-left:7px; 27 | font-family:Arial; 28 | color:#003E69; 29 | } 30 | span:hover.section { 31 | color:#336699; 32 | } 33 | span.section_title { 34 | font-weight:bold; 35 | cursor:pointer; 36 | font-size:1.125em; 37 | font-family:Arial; 38 | color:Black; 39 | } 40 | span:hover.section_title { 41 | color:#585858; 42 | } 43 | span.ext { 44 | font-weight:100; 45 | } 46 | span.ext_title { 47 | font-weight:100; 48 | } 49 | span.header { 50 | color:#cc3300; 51 | font-size:0.875em; 52 | font-weight:bold; 53 | } 54 | span.ns { 55 | color:#408080; 56 | font-size:0.94em; 57 | } 58 | span.lib_name { 59 | color:Green; 60 | font-size:0.875em; 61 | font-weight:bold; 62 | } 63 | span.libgroup { 64 | color:Black; 65 | font-size:0.875em; 66 | font-family:Arial; 67 | font-weight:bold; 68 | } 69 | span.sym_p { 70 | font-weight:normal; 71 | } 72 | table.summary { 73 | border-collapse:collapse; 74 | border:1px outset black; 75 | } 76 | table.summary th { 77 | background-color:#eeeeee; 78 | font-weight:100; 79 | text-align:left; 80 | font-size:0.94em; 81 | white-space:nowrap; 82 | border:1px inset black; 83 | padding: 3px; 84 | } 85 | table.summary td { 86 | text-align:right; 87 | white-space:nowrap; 88 | border:1px inset black; 89 | padding: 3px 5px 3px 5px; 90 | } 91 | pre { 92 | padding: 0; 93 | margin: 0; 94 | word-wrap:break-word; 95 | white-space: pre-wrap; 96 | } 97 | table.test_view { 98 | cursor:text; 99 | margin-top:7px; 100 | font-family:Monaco, Consolas, 'DejaVu Sans Mono', 'Droid Sans Mono', Monospace; 101 | font-size:14px; 102 | padding:0px; 103 | border:1px solid Black; 104 | color:#444444; 105 | background-color:White; 106 | overflow:auto; 107 | margin-left:20px; 108 | } 109 | table.test_view th { 110 | background-color:White; 111 | padding-right:3px; 112 | padding-left:3px; 113 | text-align:right; 114 | font-weight:100; 115 | padding:0px 4px 0px 10px; 116 | vertical-align:top; 117 | } 118 | table.test_view td { 119 | padding-left:15px; 120 | text-align:left; 121 | word-wrap:break-word; 122 | max-width:900px; 123 | padding:0px 15px 0px 15px; 124 | } 125 | table.test_result { 126 | margin-top:3px; 127 | line-height:16px; 128 | margin-left:20px; 129 | font-family:Arial; 130 | border:0; 131 | background-color:#FFE4E1; 132 | } 133 | table.l_num td { 134 | background-color:white; 135 | padding-right:3px; 136 | padding-left:3px; 137 | text-align:right; 138 | } 139 | table.code_lines td { 140 | padding-left:15px; 141 | text-align:left; 142 | white-space:nowrap; 143 | } 144 | span.comm { 145 | color:#888888; 146 | } 147 | span.str { 148 | color:#FF00FF; 149 | } 150 | span.var { 151 | color:Black; 152 | font-style:italic; 153 | } 154 | span.prepr { 155 | color:Green; 156 | } 157 | span.type { 158 | color:Brown; 159 | } 160 | span.keyw { 161 | font-weight:bold; 162 | } 163 | span.num { 164 | color:Blue; 165 | } 166 | span.targ { 167 | color:Red; 168 | } 169 | td.targ { 170 | background-color:#FFE4E1 171 | } 172 | span.nowrap { 173 | white-space:nowrap; 174 | } 175 | span.attr { 176 | color:#333333; 177 | font-weight:100; 178 | } 179 | span.color_p { 180 | font-style:italic; 181 | color:Brown; 182 | } 183 | span.param { 184 | font-style:italic; 185 | } 186 | span.focus_p { 187 | font-style:italic; 188 | color:Red; 189 | } 190 | .footer { 191 | font-size:0.75em; 192 | } -------------------------------------------------------------------------------- /Makefile.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | ########################################################################### 3 | # Makefile for API Sanity Checker 4 | # Install/remove the tool for GNU/Linux, FreeBSD and Mac OS X 5 | # 6 | # Copyright (C) 2009-2011 Institute for System Programming, RAS 7 | # Copyright (C) 2011-2015 Andrey Ponomarenko's ABI laboratory 8 | # 9 | # Written by Andrey Ponomarenko 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License or the GNU Lesser 13 | # General Public License as published by the Free Software Foundation. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # and the GNU Lesser General Public License along with this program. 22 | # If not, see . 23 | ########################################################################### 24 | use Getopt::Long; 25 | Getopt::Long::Configure ("posix_default", "no_ignore_case"); 26 | use File::Path qw(mkpath rmtree); 27 | use File::Spec qw(catfile file_name_is_absolute); 28 | use File::Copy qw(copy); 29 | use File::Basename qw(dirname); 30 | use Cwd qw(abs_path); 31 | use File::Find; 32 | use Config; 33 | use strict; 34 | 35 | my $TOOL_SNAME = "api-sanity-checker"; 36 | my $ARCHIVE_DIR = abs_path(dirname($0)); 37 | 38 | my $ABICC = "abi-compliance-checker"; 39 | my $ABICC_VERSION = "1.98.7"; 40 | 41 | my $HELP_MSG = " 42 | NAME: 43 | Makefile for API Sanity Checker 44 | 45 | DESCRIPTION: 46 | Install $TOOL_SNAME command and private modules. 47 | 48 | USAGE: 49 | sudo perl $0 -install -prefix /usr 50 | sudo perl $0 -remove -prefix /usr 51 | 52 | OPTIONS: 53 | -h|-help 54 | Print this help. 55 | 56 | --prefix=PREFIX 57 | Install files in PREFIX [/usr]. 58 | 59 | -install 60 | Command to install the tool. 61 | 62 | -remove 63 | Command to remove the tool. 64 | 65 | EXTRA OPTIONS: 66 | --destdir=DESTDIR 67 | This option is for maintainers to build 68 | RPM or DEB packages inside the build root. 69 | The environment variable DESTDIR is also 70 | supported. 71 | \n"; 72 | 73 | if(not @ARGV) 74 | { 75 | print $HELP_MSG; 76 | exit(0); 77 | } 78 | 79 | my ($PREFIX, $DESTDIR, $Help, $Install, $Remove); 80 | 81 | GetOptions( 82 | "h|help!" => \$Help, 83 | "prefix=s" => \$PREFIX, 84 | "destdir=s" => \$DESTDIR, 85 | "install!" => \$Install, 86 | "remove!" => \$Remove 87 | ) or exit(1); 88 | 89 | sub scenario() 90 | { 91 | if($Help) 92 | { 93 | print $HELP_MSG; 94 | exit(0); 95 | } 96 | if(not $Install and not $Remove) 97 | { 98 | print STDERR "ERROR: command is not selected (-install or -remove)\n"; 99 | exit(1); 100 | } 101 | 102 | if($Install) 103 | { # remove old version first 104 | $Remove = 1; 105 | } 106 | 107 | if(my $Version = `$ABICC -dumpversion`) 108 | { 109 | if(cmpVersions($Version, $ABICC_VERSION)<0) 110 | { 111 | print STDERR "ERROR: requires $ABICC_VERSION or newer version of \'$ABICC\'\n"; 112 | exit(1); 113 | } 114 | } 115 | else 116 | { 117 | print STDERR "ERROR: cannot find \'$ABICC\'\n"; 118 | exit(1); 119 | } 120 | if($PREFIX ne "/") { 121 | $PREFIX=~s/[\/]+\Z//g; 122 | } 123 | if(not $PREFIX) 124 | { # default prefix 125 | if($Config{"osname"}!~/win/i) { 126 | $PREFIX = "/usr"; 127 | } 128 | } 129 | if(my $Var = $ENV{"DESTDIR"}) 130 | { 131 | print "Using DESTDIR environment variable\n"; 132 | $DESTDIR = $Var; 133 | } 134 | if($DESTDIR) 135 | { 136 | if($DESTDIR ne "/") { 137 | $DESTDIR=~s/[\/]+\Z//g; 138 | } 139 | if(not isAbs($DESTDIR)) 140 | { 141 | print STDERR "ERROR: destdir is not absolute path\n"; 142 | exit(1); 143 | } 144 | if(not -d $DESTDIR) 145 | { 146 | print STDERR "ERROR: you should create destdir directory first\n"; 147 | exit(1); 148 | } 149 | $PREFIX = $DESTDIR.$PREFIX; 150 | if(not -d $PREFIX) 151 | { 152 | print STDERR "ERROR: you should create installation directory first (destdir + prefix):\n mkdir -p $PREFIX\n"; 153 | exit(1); 154 | } 155 | } 156 | else 157 | { 158 | if(not isAbs($PREFIX)) 159 | { 160 | print STDERR "ERROR: prefix is not absolute path\n"; 161 | exit(1); 162 | } 163 | if(not -d $PREFIX) 164 | { 165 | print STDERR "ERROR: you should create prefix directory first\n"; 166 | exit(1); 167 | } 168 | } 169 | 170 | print "INSTALL PREFIX: $PREFIX\n"; 171 | 172 | # paths 173 | my $EXE_PATH = catFile($PREFIX, "bin"); 174 | my $MODULES_PATH = catFile($PREFIX, "share", $TOOL_SNAME); 175 | my $REL_PATH = catFile("..", "share", $TOOL_SNAME); 176 | my $TOOL_PATH = catFile($EXE_PATH, $TOOL_SNAME); 177 | 178 | if(not -w $PREFIX) 179 | { 180 | print STDERR "ERROR: you should be root\n"; 181 | exit(1); 182 | } 183 | if($Remove) 184 | { 185 | if(-e $EXE_PATH."/".$TOOL_SNAME) 186 | { # remove executable 187 | print "-- Removing $TOOL_PATH\n"; 188 | unlink($EXE_PATH."/".$TOOL_SNAME); 189 | } 190 | elsif(not $Install) { 191 | print "The tool is not installed\n"; 192 | } 193 | 194 | if(-d $MODULES_PATH) 195 | { # remove modules 196 | print "-- Removing $MODULES_PATH\n"; 197 | rmtree($MODULES_PATH); 198 | } 199 | elsif(not $Install) { 200 | print "The modules of the tool are not installed\n"; 201 | } 202 | } 203 | if($Install) 204 | { 205 | # configure 206 | my $Content = readFile($ARCHIVE_DIR."/".$TOOL_SNAME.".pl"); 207 | if($DESTDIR) { # relative path 208 | $Content=~s/MODULES_INSTALL_PATH/$REL_PATH/; 209 | } 210 | else { # absolute path 211 | $Content=~s/MODULES_INSTALL_PATH/$MODULES_PATH/; 212 | } 213 | 214 | # copy executable 215 | print "-- Installing $TOOL_PATH\n"; 216 | mkpath($EXE_PATH); 217 | writeFile($EXE_PATH."/".$TOOL_SNAME, $Content); 218 | chmod(0755, $EXE_PATH."/".$TOOL_SNAME); 219 | 220 | if($Config{"osname"}=~/win/i) { 221 | writeFile($EXE_PATH."/".$TOOL_SNAME.".cmd", "\@perl \"$TOOL_PATH\" \%*"); 222 | } 223 | 224 | # copy modules 225 | if(-d $ARCHIVE_DIR."/modules") 226 | { 227 | print "-- Installing $MODULES_PATH\n"; 228 | mkpath($MODULES_PATH); 229 | copyDir($ARCHIVE_DIR."/modules", $MODULES_PATH); 230 | } 231 | 232 | # check PATH 233 | my $Warn = "WARNING: your PATH variable doesn't include \'$EXE_PATH\'\n"; 234 | 235 | if($Config{"osname"}=~/win/i) 236 | { 237 | if($ENV{"PATH"}!~/(\A|[:;])\Q$EXE_PATH\E[\/\\]?(\Z|[:;])/i) { 238 | print $Warn; 239 | } 240 | } 241 | else 242 | { 243 | if($ENV{"PATH"}!~/(\A|[:;])\Q$EXE_PATH\E[\/\\]?(\Z|[:;])/) { 244 | print $Warn; 245 | } 246 | } 247 | } 248 | exit(0); 249 | } 250 | 251 | sub cmpVersions($$) 252 | { # compare two versions in dotted-numeric format 253 | my ($V1, $V2) = @_; 254 | return 0 if($V1 eq $V2); 255 | my @V1Parts = split(/\./, $V1); 256 | my @V2Parts = split(/\./, $V2); 257 | for (my $i = 0; $i <= $#V1Parts && $i <= $#V2Parts; $i++) 258 | { 259 | return -1 if(int($V1Parts[$i]) < int($V2Parts[$i])); 260 | return 1 if(int($V1Parts[$i]) > int($V2Parts[$i])); 261 | } 262 | return -1 if($#V1Parts < $#V2Parts); 263 | return 1 if($#V1Parts > $#V2Parts); 264 | return 0; 265 | } 266 | 267 | sub catFile(@) { 268 | return File::Spec->catfile(@_); 269 | } 270 | 271 | sub isAbs($) { 272 | return File::Spec->file_name_is_absolute($_[0]); 273 | } 274 | 275 | sub copyDir($$) 276 | { 277 | my ($From, $To) = @_; 278 | my %Files; 279 | find(\&wanted, $From); 280 | sub wanted { 281 | $Files{$File::Find::dir."/$_"} = 1 if($_ ne "."); 282 | } 283 | foreach my $Path (sort keys(%Files)) 284 | { 285 | my $Inst = $Path; 286 | $Inst=~s/\A\Q$ARCHIVE_DIR\E/$To/; 287 | if(-d $Path) 288 | { # directories 289 | mkpath($Inst); 290 | } 291 | else 292 | { # files 293 | mkpath(dirname($Inst)); 294 | copy($Path, $Inst); 295 | } 296 | } 297 | } 298 | 299 | sub readFile($) 300 | { 301 | my $Path = $_[0]; 302 | return "" if(not $Path or not -f $Path); 303 | open(FILE, $Path) || die ("can't open file \'$Path\': $!\n"); 304 | local $/ = undef; 305 | my $Content = ; 306 | close(FILE); 307 | return $Content; 308 | } 309 | 310 | sub writeFile($$) 311 | { 312 | my ($Path, $Content) = @_; 313 | return if(not $Path); 314 | open(FILE, ">".$Path) || die ("can't open file \'$Path\': $!\n"); 315 | print FILE $Content; 316 | close(FILE); 317 | } 318 | 319 | scenario(); -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | API Sanity Checker 8 | 9 | 36 | 37 | 38 | 39 | 40 | Fork me on GitHub 41 | 42 |
43 | 44 |
45 | 46 | 47 | 48 | 49 |
50 | 51 |

API Sanity Checker

52 | 53 |
54 | An automatic generator of basic unit tests for a shared C/C++ library 55 |
56 | 57 | 58 |

59 | API Sanity Checker is an automatic generator of basic unit tests for a shared C/C++ library. It is able to generate reasonable (in most, but unfortunately not all, cases) input data for parameters and compose simple ("sanity" or "shallow"-quality) test cases for every function in the API through the analysis of declarations in header files. 60 | 61 |

62 | The quality of generated tests allows to check absence of critical errors in simple use cases. The tool is able to build and execute generated tests and detect crashes (segfaults), all kinds of emitted signals, non-zero program return code and program hanging. 63 | 64 |

65 | It may be considered as a tool for out-of-the-box low-cost sanity checking (fuzzing) of the library API or as a test development framework for initial generation of templates for advanced tests. Also it supports universal T2C format of tests, random test generation mode, specialized data types and other useful features. 66 | 67 |

68 | The tool is developed by Andrey Ponomarenko: https://abi-laboratory.pro/ 69 | 70 |
71 |
Table of Contents
72 | 89 |
90 | 91 | 92 |

Downloads

93 |

The latest release can be downloaded from this page.

94 | 95 |

Read-only access to the latest development version:

96 | 97 |  git clone git://github.com/lvc/api-sanity-checker  98 | 99 | 100 |

License

101 |

This program is free software. You may use, redistribute and/or modify it under the terms of the GNU GPL or GNU LGPL

102 | 103 | 104 |

Supported Platforms

105 | GNU/Linux, FreeBSD, Mac OS X. 106 | 107 | 108 |

Dependencies

109 |
    110 |
  • 111 | ABI Compliance Checker (1.99.24 or newer) 112 |
  • 113 |
  • 114 | G++ (3.0-4.7, 4.8.3, 4.9 or newer) 115 |
  • 116 |
  • 117 | GNU Binutils (readelf, c++filt, objdump) 118 |
  • 119 |
  • 120 | Perl 5 (5.8 or newer) 121 |
  • 122 |
  • 123 | Ctags (5.8 or newer) 124 |
  • 125 |
126 | 127 | On Mac OS X it also requires Xcode for g++, c++filt, nm and otool. 128 | 129 | 130 |

Installation

131 |

The tool is ready-to-use after extracting the archive.

132 | 133 |

You can also use a Makefile to install the tool into the system:

134 |  sudo make install prefix=PREFIX [/usr, /usr/local]  135 |

This command will install the api-sanity-checker program into the PREFIX/bin system directory and private modules into the PREFIX/share.

136 | 137 | 138 |

Usage

139 | 140 | For generating, building and running tests you should provide the XML descriptor for your library version. It is a simple XML-file that specifies version number, paths to header files and shared libraries and optionally some other information. An example of the descriptor is the following (0.3.4.xml): 141 |

142 |

143 |
144 | <version>
145 |     0.3.4
146 | </version>
147 | 
148 | <headers>
149 |     /usr/local/libssh/0.3.4/include/
150 | </headers>
151 | 
152 | <libs>
153 |     /usr/local/libssh/0.3.4/lib/
154 | </libs>
155 | 
156 |
157 |

158 | Command to generate a test suite: 159 |

160 | api-sanity-checker -lib NAME -d VER.xml -gen 161 |

162 | You can view generated tests using the index file: 163 |

164 | tests/NAME/VER/view_tests.html 165 |

166 | or manually in the directory: 167 |

168 | tests/NAME/VER/groups/ 169 |

170 | Command to build tests: 171 |

172 | api-sanity-checker -l NAME -d VER.xml -build 173 |

174 | Command to execute tests: 175 |

176 | api-sanity-checker -l NAME -d VER.xml -run 177 |

178 | The test report will be generated to: 179 |

180 | test_results/NAME/VER/test_results.html 181 |

182 | 183 | 184 |

Examples

185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
LibraryVersionNumber of TestsProblems Found
FreeType22.3.1117813
Glibc2.131996340
libX111.3.4778286
206 | 207 | 208 |

Detectable Problems

209 | 210 |
    211 |
  • 212 | Crash (segfault, signal SEGV) 213 |
  • 214 |
  • 215 | Abort (signal ABRT) 216 |
  • 217 |
  • 218 | All emitted signals: FPE, BUS, ILL and others 219 |
  • 220 |
  • 221 | Non-zero exit code 222 |
  • 223 |
  • 224 | Program hanging 225 |
  • 226 |
  • 227 | Requirement failure (if specified) 228 |
  • 229 |
230 | 231 | 232 |

Specialized Types

233 | The specialized types are used to improve quality of generated tests. You can find more info here. 234 | 235 | 236 |

Tutorial

237 | See the article at glibc wiki. 238 |

239 | 240 | 241 |

How the Tool Works

242 | The basic idea of the test data generation algorithm is to recursively initialize parameters of a function using the values returned (or returned through the out-parameter) by other functions for structured data types (class, struct, union) or by some simple values for intrinsic data types (int, float, enum, ...). The recursion step includes the heuristic selection of the appropriate function, that should be called to initialize complex parameters for other functions. If some parameter of a function cannot be initialized, then the algorithm tries to select other function. 243 |

244 | Let's see the example test for "FT_Activate_Size( FT_Size size )" function from the FreeType2 library: 245 |

246 | 247 |

248 |
249 | #include <freetype/freetype.h>
250 | int main(int argc, char *argv[])
251 | {
252 |     FT_Library alibrary = 0;
253 |     FT_Init_FreeType(&alibrary); //initialize "alibrary"
254 |     
255 |     FT_Face face = 0;
256 |     FT_New_Face(
257 |         alibrary,
258 |         "sample.ttf",
259 |         0,
260 |         &face); //initialize "face"
261 |     
262 |     FT_Size size = 0;
263 |     FT_New_Size(face, &size); //initialize "size"
264 |     
265 |     FT_Activate_Size(size); //target call
266 |     return 0;
267 | }
268 | 
269 | 
270 |
271 | 272 |

273 | 274 | In this test case the parameter "size" of target function FT_Activate_Size is initialized through the call of FT_New_Size function using its 2nd out-parameter. The first parameter "face" of FT_New_Size function is recursively initialized by the use of FT_New_Face function's 4th out-parameter. And finally the first parameter "alibrary" of FT_New_Face is initialized by the call of FT_Init_FreeType function on the 3rd recursion step. Other parameters of FT_New_Face function are initialized by intrinsic values. 275 | 276 | 277 |

Bugs

278 | Please post your bug reports, feature requests and questions to the issue tracker. 279 |

280 | 281 | 282 |

Maintainers

283 | The tool is developed by Andrey Ponomarenko. 284 | 285 | 286 |

Changes

287 | You can find changelog here. 288 | 289 | 290 |

Articles

291 | 292 | 303 | 304 | 307 | 308 |
309 |
310 | 311 |
312 | 313 | 314 | -------------------------------------------------------------------------------- /modules/Internals/RegTests.pm: -------------------------------------------------------------------------------- 1 | ########################################################################### 2 | # Module to test API Sanity Checker 3 | # 4 | # Copyright (C) 2009-2011 Institute for System Programming, RAS 5 | # Copyright (C) 2011-2015 Andrey Ponomarenko's ABI laboratory 6 | # 7 | # Written by Andrey Ponomarenko 8 | # 9 | # This program is free software: you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License or the GNU Lesser 11 | # General Public License as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # and the GNU Lesser General Public License along with this program. 20 | # If not, see . 21 | ########################################################################### 22 | use strict; 23 | 24 | my ($Debug, $LIB_EXT, $TargetCompiler); 25 | my $OSgroup = get_OSgroup(); 26 | 27 | sub testTool($$$$) 28 | { 29 | ($Debug, $LIB_EXT, $TargetCompiler) = @_; 30 | 31 | testC(); 32 | testCpp(); 33 | } 34 | 35 | sub testCpp() 36 | { 37 | printMsg("INFO", "testing C++ library API"); 38 | my ($DataDefs, $Sources) = (); 39 | my $DeclSpec = ($OSgroup eq "windows")?"__declspec( dllexport )":""; 40 | 41 | # Inline 42 | $DataDefs .= " 43 | inline int inline_func(int param) { return 0; }"; 44 | 45 | # Simple parameters 46 | $DataDefs .= " 47 | $DeclSpec int func_simple_parameters( 48 | int a, 49 | float b, 50 | double c, 51 | long double d, 52 | long long e, 53 | char f, 54 | unsigned int g, 55 | const char* h, 56 | char* i, 57 | unsigned char* j, 58 | char** k, 59 | const char*& l, 60 | const char**& m, 61 | char const*const* n, 62 | unsigned int* offset 63 | );"; 64 | $Sources .= " 65 | int func_simple_parameters( 66 | int a, 67 | float b, 68 | double c, 69 | long double d, 70 | long long e, 71 | char f, 72 | unsigned int g, 73 | const char* h, 74 | char* i, 75 | unsigned char* j, 76 | char** k, 77 | const char*& l, 78 | const char**& m, 79 | char const*const* n, 80 | unsigned int* offset ) { 81 | return 1; 82 | }"; 83 | 84 | # Initialization by interface 85 | $DataDefs .= " 86 | struct simple_struct { 87 | int m; 88 | }; 89 | $DeclSpec struct simple_struct simple_func(int a, int b);"; 90 | $Sources .= " 91 | struct simple_struct simple_func(int a, int b) 92 | { 93 | struct simple_struct x = {1}; 94 | return x; 95 | }"; 96 | 97 | $DataDefs .= " 98 | $DeclSpec int func_init_param_by_interface(struct simple_struct p);"; 99 | $Sources .= " 100 | int func_init_param_by_interface(struct simple_struct p) { 101 | return 1; 102 | }"; 103 | 104 | # Private Interface 105 | $DataDefs .= " 106 | class $DeclSpec private_class { 107 | private: 108 | private_class(){}; 109 | int a; 110 | float private_func(float p); 111 | };"; 112 | $Sources .= " 113 | float private_class::private_func(float p) { 114 | return p; 115 | }"; 116 | 117 | # Assembling structure 118 | $DataDefs .= " 119 | struct complex_struct { 120 | int a; 121 | float b; 122 | struct complex_struct* c; 123 | };"; 124 | 125 | $DataDefs .= " 126 | $DeclSpec int func_assemble_param(struct complex_struct p);"; 127 | $Sources .= " 128 | int func_assemble_param(struct complex_struct p) { 129 | return 1; 130 | }"; 131 | 132 | # Abstract class 133 | $DataDefs .= " 134 | class $DeclSpec abstract_class { 135 | public: 136 | abstract_class(){}; 137 | int a; 138 | virtual float virt_func(float p) = 0; 139 | float func(float p); 140 | };"; 141 | $Sources .= " 142 | float abstract_class::func(float p) { 143 | return p; 144 | }"; 145 | 146 | # Parameter FuncPtr 147 | $DataDefs .= " 148 | typedef int (*funcptr_type)(int a, int b); 149 | $DeclSpec funcptr_type func_return_funcptr(int a); 150 | $DeclSpec int func_param_funcptr(const funcptr_type** p);"; 151 | $Sources .= " 152 | funcptr_type func_return_funcptr(int a) { 153 | return 0; 154 | } 155 | int func_param_funcptr(const funcptr_type** p) { 156 | return 0; 157 | }"; 158 | 159 | # Parameter FuncPtr (2) 160 | $DataDefs .= " 161 | typedef int (*funcptr_type2)(int a, int b, float c); 162 | $DeclSpec int func_param_funcptr2(funcptr_type2 p);"; 163 | $Sources .= " 164 | int func_param_funcptr2(funcptr_type2 p) { 165 | return 0; 166 | }"; 167 | 168 | # Parameter Array 169 | $DataDefs .= " 170 | $DeclSpec int func_param_array(struct complex_struct const ** x);"; 171 | $Sources .= " 172 | int func_param_array(struct complex_struct const ** x) { 173 | return 0; 174 | }"; 175 | 176 | # Nested classes 177 | $DataDefs .= "//Nested classes 178 | class $DeclSpec A { 179 | public: 180 | virtual bool method1() { 181 | return false; 182 | }; 183 | }; 184 | 185 | class $DeclSpec B: public A { }; 186 | 187 | class $DeclSpec C: public B { 188 | public: 189 | C() { }; 190 | virtual bool method1(); 191 | virtual bool method2() const; 192 | };"; 193 | $Sources .= "//Nested classes 194 | bool C::method1() { 195 | return false; 196 | }; 197 | 198 | bool C::method2() const { 199 | return false; 200 | };"; 201 | 202 | # Throw class 203 | $DataDefs .= " 204 | class $DeclSpec Exception { 205 | public: 206 | Exception(); 207 | int a; 208 | };"; 209 | $Sources .= " 210 | Exception::Exception() { }"; 211 | $DataDefs .= " 212 | class $DeclSpec throw_class { 213 | public: 214 | throw_class() { }; 215 | int a; 216 | virtual float virt_func(float p) throw(Exception) = 0; 217 | float func(float p); 218 | };"; 219 | $Sources .= " 220 | float throw_class::func(float p) { 221 | return p; 222 | }"; 223 | 224 | # Should crash 225 | $DataDefs .= " 226 | $DeclSpec int func_should_crash();"; 227 | $Sources .= " 228 | int func_should_crash() 229 | { 230 | int *x = 0x0; 231 | *x = 1; 232 | return 1; 233 | }"; 234 | 235 | runSelfTests("libsample_cpp", "C++", "namespace TestNS {\n$DataDefs\n}\n", "namespace TestNS {\n$Sources\n}\n", "type_test_opaque", "_ZN18type_test_internal5func1ES_"); 236 | } 237 | 238 | sub testC() 239 | { 240 | printMsg("INFO", "\ntesting C library API"); 241 | my ($DataDefs, $Sources) = (); 242 | my $DeclSpec = ($OSgroup eq "windows")?"__declspec( dllexport )":""; 243 | 244 | # Simple parameters 245 | $DataDefs .= " 246 | $DeclSpec int func_simple_parameters( 247 | int a, 248 | float b, 249 | double c, 250 | long double d, 251 | long long e, 252 | char f, 253 | unsigned int g, 254 | const char* h, 255 | char* i, 256 | unsigned char* j, 257 | char** k);"; 258 | $Sources .= " 259 | int func_simple_parameters( 260 | int a, 261 | float b, 262 | double c, 263 | long double d, 264 | long long e, 265 | char f, 266 | unsigned int g, 267 | const char* h, 268 | char* i, 269 | unsigned char* j, 270 | char** k) { 271 | return 1; 272 | }"; 273 | 274 | # Initialization by interface 275 | $DataDefs .= " 276 | struct simple_struct { 277 | int m; 278 | }; 279 | $DeclSpec struct simple_struct simple_func(int a, int b);"; 280 | $Sources .= " 281 | struct simple_struct simple_func(int a, int b) 282 | { 283 | struct simple_struct x = {1}; 284 | return x; 285 | }"; 286 | 287 | $DataDefs .= " 288 | $DeclSpec int func_init_param_by_interface(struct simple_struct p);"; 289 | $Sources .= " 290 | int func_init_param_by_interface(struct simple_struct p) { 291 | return 1; 292 | }"; 293 | 294 | # Assembling structure 295 | $DataDefs .= " 296 | typedef struct complex_struct { 297 | int a; 298 | float b; 299 | struct complex_struct* c; 300 | } complex_struct;"; 301 | 302 | $DataDefs .= " 303 | $DeclSpec int func_assemble_param(struct complex_struct p);"; 304 | $Sources .= " 305 | int func_assemble_param(struct complex_struct p) { 306 | return 1; 307 | }"; 308 | 309 | # Initialization by out parameter 310 | $DataDefs .= " 311 | struct out_opaque_struct; 312 | $DeclSpec void create_out_param(struct out_opaque_struct** out);"; 313 | $Sources .= " 314 | struct out_opaque_struct { 315 | const char* str; 316 | }; 317 | $DeclSpec void create_out_param(struct out_opaque_struct** out) { }\n"; 318 | 319 | $DataDefs .= " 320 | $DeclSpec int func_init_param_by_out_param(struct out_opaque_struct* p);"; 321 | $Sources .= " 322 | int func_init_param_by_out_param(struct out_opaque_struct* p) { 323 | return 1; 324 | }"; 325 | 326 | # Should crash 327 | $DataDefs .= " 328 | $DeclSpec int func_should_crash();"; 329 | $Sources .= " 330 | int func_should_crash() 331 | { 332 | int *x = 0x0; 333 | *x = 1; 334 | return 1; 335 | }"; 336 | 337 | # Function with out parameter 338 | $DataDefs .= " 339 | $DeclSpec int func_has_out_opaque_param(struct out_opaque_struct* out);"; 340 | $Sources .= " 341 | int func_has_out_opaque_param(struct out_opaque_struct* out) { 342 | return 1; 343 | }"; 344 | 345 | # C++ keywords 346 | $DataDefs .= " 347 | $DeclSpec int operator();"; 348 | $Sources .= " 349 | int operator() { 350 | return 1; 351 | }"; 352 | 353 | 354 | runSelfTests("libsample_c", "C", $DataDefs, $Sources, "type_test_opaque", "func_test_internal"); 355 | } 356 | 357 | sub readFirstLine($) 358 | { 359 | my $Path = $_[0]; 360 | return "" if(not $Path or not -f $Path); 361 | open (FILE, $Path); 362 | my $FirstLine = ; 363 | close(FILE); 364 | return $FirstLine; 365 | } 366 | 367 | sub runSelfTests($$$$$$) 368 | { 369 | my ($LibName, $Lang, $DataDefs, $Sources, $Opaque, $Private) = @_; 370 | my $Ext = ($Lang eq "C++")?"cpp":"c"; 371 | # creating test suite 372 | rmtree($LibName); 373 | mkpath($LibName); 374 | writeFile("$LibName/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n"); 375 | writeFile("$LibName/libsample.h", $DataDefs."\n"); 376 | writeFile("$LibName/libsample.$Ext", "#include \"libsample.h\"\n".$Sources."\n"); 377 | writeFile("$LibName/descriptor.xml", " 378 | 379 | 1.0 380 | 381 | 382 | 383 | ".abs_path($LibName)." 384 | 385 | 386 | 387 | ".abs_path($LibName)." 388 | 389 | 390 | 391 | $Opaque 392 | 393 | 394 | 395 | $Private 396 | \n"); 397 | my @BuildCmds = (); 398 | if($OSgroup eq "windows") 399 | { 400 | if($TargetCompiler eq "CL") 401 | { 402 | push(@BuildCmds, "cl /LD libsample.$Ext >build_out 2>&1"); 403 | } 404 | else 405 | { 406 | if($Lang eq "C++") 407 | { 408 | push(@BuildCmds, "g++ -shared libsample.$Ext -o libsample.$LIB_EXT"); 409 | push(@BuildCmds, "g++ -c libsample.$Ext -o libsample.obj"); 410 | } 411 | else 412 | { 413 | push(@BuildCmds, "gcc -shared libsample.$Ext -o libsample.$LIB_EXT"); 414 | push(@BuildCmds, "gcc -c libsample.$Ext -o libsample.obj"); 415 | push(@BuildCmds, "lib libsample.obj >build_out 2>&1"); 416 | } 417 | } 418 | } 419 | elsif($OSgroup eq "linux") 420 | { 421 | writeFile("$LibName/version", "VERSION_1.0 {\n};\nVERSION_2.0 {\n};\n"); 422 | my $BCmd = ""; 423 | if($Lang eq "C++") { 424 | $BCmd = "g++ -Wl,--version-script version -shared libsample.$Ext -o libsample.$LIB_EXT"; 425 | } 426 | else { 427 | $BCmd = "gcc -Wl,--version-script version -shared libsample.$Ext -o libsample.$LIB_EXT"; 428 | } 429 | if(getArch()=~/\A(arm|x86_64)\Z/i) 430 | { # relocation R_X86_64_32S against `vtable for class' can not be used when making a shared object; recompile with -fPIC 431 | $BCmd .= " -fPIC"; 432 | } 433 | push(@BuildCmds, $BCmd); 434 | } 435 | elsif($OSgroup eq "macos") 436 | { 437 | if($Lang eq "C++") { 438 | push(@BuildCmds, "g++ -dynamiclib libsample.$Ext -o libsample.$LIB_EXT"); 439 | } 440 | else { 441 | push(@BuildCmds, "gcc -dynamiclib libsample.$Ext -o libsample.$LIB_EXT"); 442 | } 443 | } 444 | else 445 | { 446 | if($Lang eq "C++") { 447 | push(@BuildCmds, "g++ -shared libsample.$Ext -o libsample.$LIB_EXT"); 448 | } 449 | else { 450 | push(@BuildCmds, "gcc -shared libsample.$Ext -o libsample.$LIB_EXT"); 451 | } 452 | } 453 | writeFile("$LibName/Makefile", "all:\n\t".join("\n\t", @BuildCmds)."\n"); 454 | foreach (@BuildCmds) 455 | { 456 | system("cd $LibName && $_"); 457 | if($?) { 458 | exitStatus("Error", "can't compile \'$LibName/libsample.$Ext\'"); 459 | } 460 | } 461 | # running the tool 462 | my $Cmd = "perl $0 -l $LibName -d $LibName/descriptor.xml -gen -build -run -show-retval -cxx-incompatible"; 463 | 464 | if($TargetCompiler) { 465 | $Cmd .= " -target ".$TargetCompiler; 466 | } 467 | if($Debug) 468 | { 469 | $Cmd .= " -debug"; 470 | printMsg("INFO", "run $Cmd"); 471 | } 472 | system($Cmd); 473 | 474 | my $ECode = $?>>8; 475 | 476 | if($ECode!~/\A[0-1]\Z/) 477 | { # error 478 | exitStatus("Error", "analysis has failed"); 479 | } 480 | 481 | my ($Total, $Passed, $Failed) = (0, 0, 0); 482 | if(my $FLine = readFirstLine("test_results/$LibName/1.0/test_results.html")) 483 | { 484 | if($FLine=~/total:(\d+)/) { 485 | $Total = $1; 486 | } 487 | if($FLine=~/passed:(\d+)/) { 488 | $Passed = $1; 489 | } 490 | if($FLine=~/failed:(\d+)/) { 491 | $Failed = $1; 492 | } 493 | } 494 | if($Total==($Passed+$Failed) and (($LibName eq "libsample_c" and $Total>5 and $Failed==1) 495 | or ($LibName eq "libsample_cpp" and $Total>10 and $Failed==1))) { 496 | printMsg("INFO", "result: SUCCESS ($Total test cases, $Passed passed, $Failed failed)\n"); 497 | } 498 | else { 499 | printMsg("ERROR", "result: FAILED ($Total test cases, $Passed passed, $Failed failed)\n"); 500 | } 501 | } 502 | 503 | return 1; -------------------------------------------------------------------------------- /doc/Xml-Descriptor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | XML Descriptor 7 | 8 | 36 | 37 | 38 | 39 | 40 | Fork me on GitHub 41 | 42 |
43 | 44 |

XML-Descriptor

45 |

46 | The library descriptor is a simple XML-file that specifies version number, paths to header files and shared libraries and optionally some other information. 47 |

48 | 49 |
50 |
Table of Contents
51 | 57 |
58 | 59 | 60 |

Primary Sections

61 |
62 |
 63 | <version>
 64 |     /* Version of the library */
 65 | </version>
 66 | 
 67 | <headers>
 68 |     /* The list of paths to header files or/and
 69 |        directories with header files, one per line */
 70 | </headers>
 71 | 
 72 | <libs>
 73 |     /* The list of paths to shared libraries or/and
 74 |        directories with shared libraries, one per line */
 75 | </libs>
 76 | 
77 |
78 |

79 | 80 | 81 |

Optional Sections

82 |
83 |
 84 | <include_paths>
 85 |     /* The list of paths to be searched for header files
 86 |        needed for compiling of library headers, one per
 87 |        line. NOTE: If you define this section then the tool
 88 |        will not automatically detect include paths */
 89 | </include_paths>
 90 | 
 91 | <add_include_paths>
 92 |     /* The list of include paths that should be added
 93 |     to the automatically detected include paths, one per
 94 |     line */
 95 | </add_include_paths>
 96 | 
 97 | <skip_include_paths>
 98 |     /* The list of include paths that will be removed from
 99 |     the list of automatically generated include paths, one
100 |     per line */
101 | </skip_include_paths>
102 | 
103 | <gcc_options>
104 |     /* Additional GCC options, one per line */
105 | </gcc_options>
106 | 
107 | <include_preamble>
108 |     /* The list of header files that should be included
109 |     before other headers, one per line. For example, it
110 |     is a tree.h for libxml2 and ft2build.h for freetype2
111 |     library */
112 | </include_preamble>
113 | 
114 | <defines>
115 |     /* Add defines at the headers compiling stage, one per
116 |     line:
117 |         #define A B
118 |         #define C D */
119 | </defines>
120 | 
121 | <add_namespaces>
122 |     /* The list of namespaces that should be added to the
123 |     alanysis  if the tool cannot find them automatically,
124 |     one per line */ 
125 | </add_namespaces>
126 | 
127 | <skip_types>
128 |     /* The list of data types, that
129 |     should not be checked, one per line */
130 | </skip_types>
131 | 
132 | <skip_symbols>
133 |     /* The list of functions (mangled/symbol names in C++),
134 |     that should not be checked, one per line */
135 | </skip_symbols>
136 | 
137 | <skip_namespaces>
138 |     /* The list of C++ namespaces, that
139 |     should not be checked, one per line */
140 | </skip_namespaces>
141 | 
142 | <skip_constants>
143 |     /* The list of constants that should not be checked,
144 |     one name per line */
145 | </skip_constants>
146 | 
147 | <skip_headers>
148 |     /* The list of header files and/or directories
149 |     with header files that should not be checked, one per
150 |     line */
151 | </skip_headers>
152 | 
153 | <skip_libs>
154 |     /* The list of shared libraries and/or directories
155 |     with shared libraries that should not be checked, one
156 |     per line */
157 | </skip_libs>
158 | 
159 | <skip_including>
160 |     /* The list of header files, that cannot be included
161 |     directly (or non-self compiled ones), one per line */
162 | </skip_including>
163 | 
164 | <search_headers>
165 |     /* List of directories to be searched
166 |     for header files to automatically
167 |     generate include paths, one per line */
168 | </search_headers>
169 | 
170 | <search_libs>
171 |     /* List of directories to be searched
172 |     for shared librariess to resolve
173 |     dependencies, one per line */
174 | </search_libs>
175 | 
176 | <tools>
177 |     /* List of directories with tools used
178 |     for analysis (GCC toolchain), one per line */
179 | </tools>
180 | 
181 | <cross_prefix>
182 |     /* GCC toolchain prefix.
183 |     Examples:
184 |         arm-linux-gnueabi
185 |         arm-none-symbianelf */
186 | </cross_prefix>
187 | 
188 |
189 |

190 | 191 | 192 |

Extra Sections for API Sanity Checker

193 |
194 |
195 | <test_include_preamble>
196 |     /* The list of header files that should be
197 |        included in each test case before other
198 |        headers, one per line */
199 | </test_include_preamble>
200 | 
201 | <test_defines>
202 |     /* Add defines to test cases */
203 | </test_defines>
204 | 
205 | <libs_depend>
206 |     /* The list of paths to libraries that should be
207 |        provided to gcc for resolving undefined symbols
208 |        (if NEEDED elf section doesn't include them) */
209 | </libs_depend>
210 | 
211 | <opaque_types>
212 |     /* The list of opaque types, one per line */
213 | </opaque_types>
214 | 
215 | <libgroup>
216 |     <name>
217 |         /* Name of the libgroup */
218 |     </name>
219 | 
220 |     <symbols>
221 |         /* The list of symbols (mangled names in C++)
222 |            in the group that should be tested, one
223 |            per line */
224 |     </symbols>
225 | </libgroup>
226 | 
227 | <out_params>
228 |     /* Associating of out(returned)-parameters
229 |        with symbols, one entry per line:
230 |           symbol:param_name
231 |                 or
232 |           symbol:param_number
233 |        Examples:
234 |           dbus_parse_address:entry
235 |           dbus_parse_address:2       */
236 | </out_params>
237 | 
238 | <skip_warnings>
239 |     /* The list of warnings that should not be shown in
240 |        the report, one pattern per line */
241 | </skip_warnings>
242 | 
243 | 
244 |
245 |

246 | 247 | 248 |

Examples

249 | 250 | libssh: 251 |
252 |
253 | <version>
254 |     0.3.4
255 | </version>
256 | 
257 | <headers>
258 |     /usr/local/libssh/0.3.4/include/
259 | </headers>
260 | 
261 | <libs>
262 |     /usr/local/libssh/0.3.4/lib/
263 | </libs>
264 | 
265 |
266 |

267 | 268 | atk: 269 |

270 |
271 | <version>
272 |     1.28.0
273 | </version>
274 | 
275 | <headers>
276 |     /usr/local/atk-1.28.0/include/atk-1.0/atk/atk.h
277 | </headers>
278 | 
279 | <libs>
280 |     /usr/local/atk-1.28.0/lib/
281 | </libs>
282 | 
283 | <include_paths>
284 |     /usr/include/glib-2.0/
285 |     /usr/lib/glib-2.0/include/
286 | </include_paths>
287 | 
288 |
289 |

290 | 291 | libxml2: 292 |

293 |
294 | <version>
295 |     2.7.6
296 | </version>
297 | 
298 | <headers>
299 |     /usr/local/libxml2-2.7.6/include/
300 | </headers>
301 | 
302 | <libs>
303 |     /usr/local/libxml2-2.7.6/lib/libxml2.so.2.7.6
304 | </libs>
305 | 
306 | <include_preamble>
307 |     tree.h
308 | </include_preamble>
309 | 
310 |
311 |

312 | 313 | libX11: 314 |

315 |
316 | <version>
317 |     1.3.2
318 | </version>
319 | 
320 | <headers>
321 |     /usr/local/libX11-1.3.2/include/
322 | </headers>
323 | 
324 | <libs>
325 |     /usr/local/libX11-1.3.2/lib/
326 | </libs>
327 | 
328 | <include_preamble>
329 |     Xlib.h
330 | </include_preamble>
331 | 
332 |
333 |

334 | 335 | BlackBerry 10 Native SDK: 336 |

337 |
338 | <version>
339 |     10
340 | </version>
341 | 
342 | <headers>
343 |     /home/RIM/bbndk/target_10_0_9_1673/qnx6/usr/include/bb/
344 | </headers>
345 | 
346 | <search_headers>
347 |     /home/RIM/bbndk/target_10_0_9_1673/qnx6/usr/include/
348 | </search_headers>
349 | 
350 | <libs>
351 |     /home/RIM/bbndk/target_10_0_9_1673/qnx6/x86/usr/lib/
352 | </libs>
353 | 
354 | <tools>
355 |     /home/RIM/bbndk/host_10_0_9_404/linux/x86/usr/bin/
356 | </tools>
357 | 
358 | <cross_prefix>
359 |     i486-pc-nto-qnx8.0.0
360 | </cross_prefix>
361 | 
362 |
363 |

364 | 365 | libQt5Core: 366 |

367 |
368 | <version>
369 |     5.5.0
370 | </version>
371 | 
372 | <headers>
373 |     /usr/local/Qt-5.5.0/include/QtCore
374 | </headers>
375 | 
376 | <libs>
377 |     /usr/local/Qt-5.5.0/lib/libQt5Core.so.5.5.0
378 | </libs>
379 | 
380 | <include_paths>
381 |     /usr/local/Qt-5.5.0/include/
382 | </include_paths>
383 | 
384 | <skip_headers>
385 |     /private/
386 |     qt_windows.h
387 |     qatomic_*
388 |     *_impl.h
389 | </skip_headers>
390 |  
391 | <gcc_options>
392 |     -fvisibility=hidden
393 |     -fvisibility-inlines-hidden
394 |     -fPIC
395 |     -Wall
396 |     -W
397 |     -D_REENTRANT
398 |     -DQT_NO_CAST_FROM_ASCII
399 |     -DQT_NO_CAST_TO_ASCII
400 |     -DQT_NO_STL
401 |     -DQT_SHARED
402 | </gcc_options>
403 | 
404 |
405 |

406 | 407 | libxslt: 408 |

409 |
410 | <version>
411 |     1.1.22
412 | </version>
413 | 
414 | <headers>
415 |     /usr/local/libxslt-1.1.22/include/
416 | </headers>
417 | 
418 | <libs>
419 |     /usr/local/libxslt-1.1.22/lib/libxslt.so
420 |     /usr/local/libxslt-1.1.22/lib/libexslt.so
421 | </libs>
422 | 
423 | <include_paths>
424 |     /usr/include/libxml2/
425 | </include_paths>
426 | 
427 | <include_preamble>
428 |     xsltInternals.h
429 | </include_preamble>
430 | 
431 |
432 |

433 | 434 | libxml++: 435 |

436 |
437 | <version>
438 |     2.26.1
439 | </version>
440 | 
441 | <headers>
442 |     /usr/local/libxml++-2.26.1/include/
443 |     /usr/local/libxml++-2.26.1/lib/libxml++-2.6/include/
444 | </headers>
445 | 
446 | <libs>
447 |     /usr/local/libxml++-2.26.1/lib/
448 | </libs>
449 | 
450 | <include_paths>
451 |     /usr/include/glib-2.0/
452 |     /usr/lib/glib-2.0/include/
453 |     /usr/include/glibmm-2.4/
454 |     /usr/lib/glibmm-2.4/include/
455 | </include_paths>
456 | 
457 |
458 |

459 | 460 | pango: 461 |

462 |
463 | <version>
464 |     1.26.0
465 | </version>
466 | 
467 | <headers>
468 |     /usr/local/pango-1.26.0/include/
469 | </headers>
470 | 
471 | <libs>
472 |     /usr/local/pango-1.26.0/lib/
473 | </libs>
474 | 
475 | <include_paths>
476 |     /usr/include/glib-2.0/
477 |     /usr/lib/glib-2.0/include/
478 |     /usr/include/cairo/
479 |     /usr/include/freetype2/
480 |     /usr/include/X11/
481 | </include_paths>
482 | 
483 | <include_preamble>
484 |     pango.h
485 | </include_preamble>
486 | 
487 |
488 |

489 | 490 | gtk+: 491 |

492 |
493 | <version>
494 |     2.18.4
495 | </version>
496 | 
497 | <headers>
498 |     /usr/local/gtk+-2.18.4/include/gtk-2.0/gdk/gdk.h
499 |     /usr/local/gtk+-2.18.4/include/gtk-2.0/gtk/gtk.h
500 |     /usr/local/gtk+-2.18.4/include/gail-1.0/
501 |     /usr/local/gtk+-2.18.4/include/gtk-unix-print-2.0/
502 | </headers>
503 | 
504 | <libs>
505 |     /usr/local/gtk+-2.18.4/lib/
506 | </libs>
507 | 
508 | <include_paths>
509 |     /usr/include/atk-1.0/
510 |     /usr/include/glib-2.0/
511 |     /usr/lib/glib-2.0/include/
512 |     /usr/include/cairo/
513 |     /usr/include/pango-1.0/
514 | </include_paths>
515 | 
516 |
517 |

518 | 519 | glib: 520 |

521 |
522 | <version>
523 |     2.22.2
524 | </version>
525 | 
526 | <headers>
527 |     /usr/local/glib-2.22.2/include/glib-2.0/glib.h
528 |     /usr/local/glib-2.22.2/include/glib-2.0/glib-object.h
529 |     /usr/local/glib-2.22.2/include/glib-2.0/gmodule.h
530 | </headers>
531 | 
532 | <libs>
533 |     /usr/local/glib-2.22.2/lib/
534 | </libs>
535 | 
536 | <include_paths>
537 |     /usr/local/glib-2.22.2/lib/glib-2.0/include/
538 | </include_paths>
539 | 
540 |
541 |

542 | 543 | libsoup: 544 |

545 |
546 | <version>
547 |     2.28.0
548 | </version>
549 | 
550 | <headers>
551 |     /usr/local/libsoup-2.28.0/include/
552 | </headers>
553 | 
554 | <libs>
555 |     /usr/local/libsoup-2.28.0/lib/
556 | </libs>
557 | 
558 | <include_paths>
559 |     /usr/include/glib-2.0/
560 |     /usr/lib/glib-2.0/include/
561 | </include_paths>
562 | 
563 |
564 |

565 | 566 | allegro: 567 |

568 |
569 | <version>
570 |     4.9.9.1
571 | </version>
572 | 
573 | <headers>
574 |     /usr/local/include/allegro5/allegro.h
575 | </headers>
576 | 
577 | <libs>
578 |     /usr/local/lib/liballegro-4.9.9.so
579 | </libs>
580 | 
581 |
582 |

583 | 584 | mathgl: 585 |

586 |
587 | <version>
588 |     1.9.0.1
589 | </version>
590 | 
591 | <headers>
592 |     /usr/local/mathgl-1.9.0.1/include/
593 | </headers>
594 | 
595 | <libs>
596 |     /usr/local/mathgl-1.9.0.1/lib/
597 | </libs>
598 | 
599 | <include_paths>
600 |     /usr/local/gsl-1.9/include/
601 | </include_paths>
602 | 
603 |
604 |

605 | 606 | gsl: 607 |

608 |
609 | <version>
610 |     1.9
611 | </version>
612 | 
613 | <headers>
614 |     /usr/local/gsl-1.9/include/
615 | </headers>
616 | 
617 | <libs>
618 |     /usr/local/gsl-1.9/lib/
619 | </libs>
620 | 
621 | <include_preamble>
622 |     stdlib.h
623 | </include_preamble>
624 | 
625 |
626 |

627 | 628 | libjpeg: 629 |

630 |
631 | <version>
632 |     7
633 | </version>
634 | 
635 | <headers>
636 |     /usr/local/libjpeg-7/include/jpeglib.h
637 | </headers>
638 | 
639 | <libs>
640 |     /usr/local/libjpeg-7/lib/
641 | </libs>
642 | 
643 | <include_preamble>
644 |     stdio.h
645 | </include_preamble>
646 | 
647 |
648 |

649 | 650 |

653 | 654 |
655 |
656 | 657 |
658 | 659 | 660 | -------------------------------------------------------------------------------- /doc/Specialized-Type.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Specialized Type 7 | 8 | 36 | 37 | 38 | 39 | 40 | Fork me on GitHub 41 | 42 |
43 | 44 |

Specialized Type

45 |

46 | The basic idea of specialized types is to provide the test generator (the API Sanity Checker tool) with enough information to generate correct invocation of the target interface in a typical use case and check basic constraints on the return value. The issue is that, for many interfaces, correct invocation requires preparing correct environment and correct parameter values. And this in turn may require calling other interfaces. 47 |

48 | 49 | Specialized type (or "semantic type" of parameter) include information about various initialization means for various environments. Such information can be reused for multiple interfaces each time the same semantic types are used, which greatly speeds up the development. Correct values for simple types are created by generator completely automatically. When an interface has initialization means assigned for all of its parameters (and if necessary for initial environment), the generator can automatically compose a test for this interface. 50 |

51 | Test development process consists in creating the complete collection of specialized types for the library. Testing of libraries with numerous interfaces by this methodology requires relatively small effort per test and thus is cheap enough. The efficiency is best revealed for interface sets with the number of interfaces starting from hundreds. 52 |

53 | 54 |
55 |
Table of Contents
56 | 65 |
66 | 67 | 68 |

C/C++ Language Extensions

69 | Attributes of specialized type should be described on C/C++ language extended by the following instructions: 70 |

71 | $(type) - instruction initializing an instance of data type. 72 |

73 |

74 | void create_QAbstractProxyModel(QAbstractProxyModel* Obj) 75 | { 76 |
 77 |     Obj->setSourceModel( $(QAbstractItemModel*) );
78 | } 79 |
80 |

81 | 82 | $[interface] - instruction for interface call with properly initialized parameters. 83 |

84 |

85 | xmlListPtr create_filled_list() 86 |
{ 87 |
 88 |     xmlListPtr l=$[xmlListCreate];
 89 |     int num=100;
 90 |     xmlListPushBack(l,&num);
 91 |     return l;
92 | } 93 |
94 |

95 | 96 | $0 - an instance of the specialized type. 97 |

98 |

99 | /*initialize "doc" property of the associated parameter*/ 100 |
$0->doc = xmlParseMemory("<p/>",4); 101 |
102 |

103 | 104 | $1, $2, ... - references to 1st, 2nd and other interface parameters. 105 |

106 |

107 | /*initialize "next" field of the first parameter by the second parameter*/ 108 |
$1->next=$2; 109 |
110 |

111 | 112 |

113 | /*write first parameter to the second parameter*/ 114 |
$2.write($1); 115 |
116 |

117 | 118 | $obj - reference to the object that current method calls on (C++ only). 119 |

120 |

121 | /*call setStyle() method on the object*/ 122 |
$obj.setStyle(Qt::DotLine); 123 |
124 |

125 | 126 | 127 |

Attributes of Specialized Type

128 | Specialized type has the following attributes: 129 | 130 | name - Name of the specialized type 131 |

132 | data_type - Name of the associated real data type (QObject*, int, xmlChar ...) or the list of such types (one per line) 133 |

134 | value - Value for initialization (true, 1.0, "string") 135 |

136 | pre_condition/post_condition - Pre/Postcondition on associated function return value or parameter 137 |

138 |

139 | $0!=NULL 140 |
141 |

142 | init_code/final_code - Code that should be invoked before/after function call 143 |

144 | /*call the start() method on the associated parameter*/ 145 |
$0->start(); 146 |
147 |

148 | global_code - Declarations of auxiliary functions and global variables, header includes 149 |

150 | #include <QWidgetAction> 151 |
QWidgetAction* create_QWidgetAction() 152 |
{ 153 |
154 |     QWidgetAction* Obj = new QWidgetAction($(QWidget*));
155 |     Obj->setDefaultWidget($(QWidget*));
156 |     return Obj;
157 | } 158 |
159 |

160 | libs - List of external shared objects used by this type. Corresponding external header files should be included in the global_code section 161 |

162 | kind - Kind of the specialized type: 163 |

    164 |
  • 165 | normal - This specialized type should be manually associated with the parameters or return values of suitable interfaces 166 |
  • 167 |
  • 168 | common_param - This specialized type will be automatically associated with the parameters of all suitable interfaces 169 |
  • 170 |
  • 171 | common_retval - This specialized type will be automatically associated with the return values of all suitable interfaces 172 |
  • 173 |
  • 174 | env - This kind of specialized type was introduced for setting up correct environment for the interfaces. The code of this specialized type will be added once at the beginning or at the end of main() function in the test for manually associated interface 175 |
  • 176 |
  • 177 | common_env - This kind of specialized type is the same as env, but will be automatically associated with all library interfaces 178 |
  • 179 |
180 | 181 | 182 |

Associating with Interfaces

183 | Specialized Types should be associated with the return values or parameters of some library interfaces. Base type of the specialized type should be the same as base type of return value or parameter. For example, specialized type with data_type=int* can be associated with any parameter that has int as the base type like int, int**, int&* and others (it is a family of data types - collection of types that have the same base type). 184 | 185 | 186 |

Writing Specialized Types

187 | Specialized Type has XML-like structure (you can skip any section if it is not needed): 188 |

189 | 190 |

191 | 192 | <spec_type> 193 |
194 |    <kind>
195 |       /* Kind of the specialized type.
196 |          Select it from the following list:
197 |            normal
198 |            common_param
199 |            common_retval
200 |            env
201 |            common_env */
202 |    </kind>
203 |  
204 |    <data_type>
205 |       /* Name of the corresponding real data type,
206 |          one per line. You can specify several data
207 |          types if kind is 'common_param' or
208 |          'common_retval', one per line. This section
209 |          is not used if kind is 'env' or
210 |          'common_env' */
211 |    </data_type>
212 |    
213 |    <value>
214 |       /* Value for initialization (true, 1.0,
215 |          "string", ...) */
216 |    </value>
217 |    
218 |    <pre_condition>
219 |       /* Precondition on associated function parameter.
220 |           Example: $0!=NULL */
221 |    </pre_condition>
222 |    
223 |    <post_condition>
224 |       /* Postcondition on associated function return
225 |          value or parameter.
226 |           Example: $0!=NULL && $obj.style() == DotLine
227 |        */
228 |    </post_condition>
229 |    
230 |    <init_code>
231 |       /* Code that should be invoked before function call.
232 |           Example: $0->start(); */
233 |    </init_code>
234 |    
235 |    <final_code>
236 |       /* Code that should be invoked after function call.
237 |           Example: $0->end(); */
238 |    </final_code>
239 |    
240 |    <global_code>
241 |       /* Declarations of auxiliary functions and global
242 |          variables, header includes */
243 |    </global_code>
244 |    
245 |    <decl_code>
246 |         /* Code that will be pasted instead of parameter
247 |            automatic declaration. Example: char \$0[16]; */
248 |    </decl_code>
249 |    
250 |    <associating>
251 |       <interfaces>
252 |          /* List of interfaces (mangled/symbol names in
253 |             C++) that will be associated with the
254 |             specialized type, one per line */
255 |       </interfaces>
256 |        
257 |       <except>
258 |          /* List of interfaces (mangled/symbol names in
259 |             C++) that will not be associated with the
260 |             specialized type, one per line. This section
261 |             is used if kind is 'common_env',
262 |             'common_param' or 'common_return' */
263 |       </except>
264 |       
265 |       <links>
266 |          /* Associations with the return value,
267 |             parameters or/and object, one per line:
268 |               param1
269 |               param2
270 |                ...
271 |               object
272 |               retval */
273 |       </links>
274 |       
275 |       <param_name>
276 |          /* Associations with the parameters by name,
277 |             one per line:
278 |               param_name1
279 |               param_name2
280 |               param_name3
281 |                ...
282 |                      */
283 |       </param_name>
284 |    </associating>
285 |    
286 |    <associating>
287 |        /* Other associations */
288 |    </associating>
289 |    
290 |    <name>
291 |        /* Name of the specialized type */
292 |    </name>
293 |    
294 |    <libs>
295 |        /* External shared objects, one per line.
296 |           If spectype contains call of the functions from
297 |           some external shared objects then these objects
298 |           should be listed here. Corresponding external
299 |           header files should be included in global_code */
300 |    </libs>
301 | </spec_type> 302 |
303 | 304 | 305 |

Collections of Specialized Types

306 | You can unite several specialized types into collection(s): 307 |
308 |
309 | <collection>
310 |  
311 |      <spec_type>
312 |          /* Specialized Type №1 */
313 |      </spec_type>
314 |      
315 |      <spec_type>
316 |          /* Specialized Type №2 */
317 |      </spec_type>
318 |      
319 |         ...
320 |     
321 | </collection>
322 | 
323 | <collection>
324 |     /* Other Collection */
325 | </collection>
326 | 
327 |
328 |

329 | The file containing collection(s) of specialized types can be provided to the API Sanity Checker tool by the -specialized-types (-st) option: 330 |

331 | api-sanity-checker -specialized-types SPECTYPES.xml -gen -build -run 332 | 333 | 334 |

Using Test Data

335 | Test data (special files needed by tests) should be created in some directory before generating tests. Path to that directory should be provided to API Sanity Checker tool by the -test-data (-td) option: 336 |

337 | api-sanity-checker -test-data DIR -specialized-types SPECTYPES.xml -gen -build -run 338 |

339 | For accessing test data files in the attributes of specialized types you should use TEST_DATA_PATH("file") construction. Test generator will copy specified file to the local "testdata/" directory and replace TEST_DATA_PATH("file") with the "testdata/file" in the generated code. 340 |

341 |
342 | QSound* create_QSound()
343 | {
344 |     QSound* Obj=new QSound(TEST_DATA_PATH("SoundFile.wav"));
345 |     Obj->setLoops(5);
346 |     return Obj;
347 | }
348 | 
349 |
350 | 351 | 352 |

Examples

353 | Setting up environment for all interfaces and correct initialization for parameters of type GObject* in the ATK library: 354 |

355 |

356 |
357 |  <spec_type>
358 |      <kind>
359 |          common_env
360 |      </kind>
361 |  
362 |      <init_code>
363 |          g_type_init();
364 |      </init_code>
365 |  </spec_type>
366 |  
367 |  <spec_type>
368 |      <kind>
369 |          common_param
370 |      </kind>
371 |  
372 |      <data_type>
373 |          GObject*
374 |      </data_type>
375 |     
376 |      <value>
377 |          g_object_new (G_TYPE_OBJECT, NULL)
378 |      </value>
379 |     
380 |      <global_code>
381 |          #include <glib.h>
382 |      </global_code>
383 |  </spec_type>
384 | 
385 |
386 |

387 | 388 | Correct initialization for all parameters of type xmlListPtr in the libxml2 library: 389 |

390 |

391 |
392 |  <spec_type>
393 |      <kind>
394 |          common_param
395 |      </kind>
396 |  
397 |      <data_type>
398 |          xmlListPtr
399 |      </data_type>
400 |     
401 |      <value>
402 |          create_filled_list()
403 |      </value>
404 |     
405 |      <constraint>
406 |          $0!=NULL
407 |      </constraint>
408 |     
409 |      <global_code>
410 |          xmlListPtr create_filled_list()
411 |          {
412 |              xmlListPtr l = $[xmlListCreate];
413 |              int num = 100;
414 |              xmlListPushBack(l, &num);
415 |              return l;
416 |          }
417 |      </global_code>
418 |  </spec_type>
419 | 
420 |
421 |

422 | 423 | Correct initialization for the 1st parameter of interface xmlListAppend(xmlListPtr l, void* data) from libxml2 library: 424 |

425 |

426 |
427 |  <spec_type>
428 |      <kind>
429 |          normal
430 |      </kind>
431 |      
432 |      <data_type>
433 |          xmlListPtr
434 |      </data_type>
435 |      
436 |      <value>
437 |          create_filled_list()
438 |      </value>
439 |  
440 |      <global_code>
441 |          xmlListPtr create_filled_list()
442 |          {
443 |              xmlListPtr l = $[xmlListCreate];
444 |              int num = 100;
445 |              xmlListPushBack(l, &num);
446 |              return l;
447 |          }
448 |      </global_code>
449 |      
450 |      <associating>
451 |          <interfaces>
452 |              xmlListAppend
453 |          </interfaces>
454 |        
455 |          <links>
456 |              param1
457 |          </links>
458 |      </associating>
459 |  </spec_type>
460 | 
461 |
462 |

463 | 464 | Setting up environment for all interfaces from the libQt5Core library: 465 |

466 |

467 |
468 |  <spec_type>
469 |      <kind>
470 |          common_env
471 |      </kind>
472 |  
473 |      <global_code>
474 |          #include<QApplication>
475 |          #include<QTimer>
476 |      </global_code>
477 |  
478 |      <init_code>
479 |          #ifdef Q_WS_X11
480 |            bool useGUI = getenv( "DISPLAY" ) != 0;
481 |          #else
482 |            bool useGUI = TRUE;
483 |          #endif
484 |          QApplication* app = new QApplication(argc, argv,
485 |                                               useGUI);
486 |      </init_code>
487 |  
488 |      <final_code>
489 |          QTimer::singleShot(100, app, SLOT(quit()));
490 |          app->exec();
491 |      </final_code>
492 |  </spec_type>
493 | 
494 |
495 |

496 | 497 | Setting up environment for all interfaces from the Gtk+ library: 498 |

499 |

500 |
501 |  <spec_type>
502 |      <kind>
503 |          common_env
504 |      </kind>
505 |  
506 |      <init_code>
507 |          gtk_init(&argc, &argv);
508 |      </init_code>
509 |  
510 |      <final_code>
511 |         gtk_timeout_add(100, &main_loop_quit, NULL);
512 |         gtk_main();
513 |      </final_code>
514 |  
515 |      <global_code>
516 |          #include <gtk.h>
517 |          gboolean main_loop_quit(gpointer data)
518 |          {
519 |              gtk_main_quit();
520 |              return FALSE;
521 |          }
522 |      </global_code>
523 |  
524 |      <associating>
525 |          <except>
526 |              gtk_init
527 |              gtk_init_check
528 |              gtk_parse_args
529 |              gdk_init
530 |              gdk_init_check
531 |              gdk_parse_args
532 |              gtk_test_init
533 |          </except>
534 |      </associating>
535 |  </spec_type>
536 | 
537 |
538 |

539 | 540 | Using test data for initializing all parameters of type xmlTextReaderPtr in the libxml2 library: 541 |

542 |

543 |
544 |  <spec_type>
545 |      <kind>
546 |          common_param
547 |      </kind>
548 |      
549 |      <data_type>
550 |          xmlTextReaderPtr
551 |      </data_type>
552 |      
553 |      <value>
554 |          create_reader()
555 |      </value>
556 |  
557 |      <global_code>
558 |          xmlTextReaderPtr create_reader(int n)
559 |          {
560 |              xmlTextReaderPtr reader = xmlReaderForFile(TEST_DATA_PATH("file.xml"), NULL, 0);
561 |              int i;
562 |              for(i=0; i<n; i+=1)
563 |              {
564 |                  xmlTextReaderRead(reader);
565 |              }
566 |              return reader;
567 |          }
568 |      </global_code>
569 |  </spec_type>
570 | 
571 |
572 |

573 | 574 | Checking the return value of interface xmlLinkGetData(xmlLinkPtr lk) from the libxml2 library: 575 |

576 |

577 |
578 |  <spec_type>
579 |      <kind>
580 |          normal
581 |      </kind>
582 |  
583 |      <data_type>
584 |          void*
585 |      </data_type>
586 |  
587 |      <constraint>
588 |          $0!=NULL
589 |      </constraint>
590 |      
591 |      <associating>
592 |          <interfaces>
593 |              xmlLinkGetData
594 |          </interfaces>
595 |        
596 |          <links>
597 |              retval
598 |          </links>
599 |      </associating>
600 |  </spec_type>
601 | 
602 |
603 |

604 | 605 |

608 | 609 |
610 |
611 | 612 |
613 | 614 | 615 | -------------------------------------------------------------------------------- /doc/Changelog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | API Sanity Checker: Changelog 7 | 8 | 35 | 36 | 37 | 38 | 39 | Fork me on GitHub 40 | 41 |
42 | 43 |

API Sanity
Checker: History

44 |

45 |
46 | 47 | Version 1.98.7 (September 08, 2015)
48 | Improvements 49 |

    50 |
  • 51 | Ability to run or build old test-suite on a new library version for compatibility analysis 52 |
  • 53 |
  • 54 | Improved style of the report 55 |
  • 56 |
57 | Bug Fixes 58 |
    59 |
  • 60 | Fixed tests for abstract methods 61 |
  • 62 |
  • 63 | Fixed self-tests 64 |
  • 65 |
  • 66 | Disabled tests for C3/C4 c-tors and D3/D4 d-tors 67 |
  • 68 |
  • 69 | Fixed test result handling 70 |
  • 71 |
  • 72 | Fixed sorting of selected interfaces 73 |
  • 74 |
  • 75 | Fixed handling of relative paths in the descriptor 76 |
  • 77 |
  • 78 | Added -all option 79 |
  • 80 |
  • 81 | Corrected usage of typedefs in tests 82 |
  • 83 |
  • 84 | Updated documentation 85 |
  • 86 |
87 |
88 | 89 | Version 1.98.6 (September 17, 2013)
90 | Bug Fixes 91 |
    92 |
  • 93 | Support for ABI Compliance Checker 1.99.8.3 94 |
  • 95 |
  • 96 | Corrected generated test cases code and Makefiles 97 |
  • 98 |
  • 99 | Support for SUSE 11.2 100 |
  • 101 |
102 | Other 103 |
    104 |
  • 105 | Code cleaning 106 |
  • 107 |
108 |
109 | 110 | Version 1.98.3 (February 07, 2013)
111 | New Options 112 |
    113 |
  • 114 | -target 115 |
  • 116 |
117 | Bug Fixes 118 |
    119 |
  • 120 | Corrected formatting of generated HTML-pages 121 |
  • 122 |
  • 123 | Corrected generated makefiles 124 |
  • 125 |
  • 126 | Corrected -vnum option 127 |
  • 128 |
  • 129 | Other fixes 130 |
  • 131 |
132 | Other 133 |
    134 |
  • 135 | Code cleaning 136 |
  • 137 |
138 |
139 | 140 | Version 1.98.2 (January 10, 2013)
141 | Bug Fixes 142 |
    143 |
  • 144 | Fixed a problem with resolving of undefined symbols 145 |
  • 146 |
  • 147 | Moved linker options to LIBS variable in generated makefiles 148 |
  • 149 |
150 |
151 | 152 | Version 1.98 (December 14, 2012)
153 | New Options 154 |
    155 |
  • 156 | -optimize-includes 157 |
  • 158 |
  • 159 | -no-inline 160 |
  • 161 |
  • 162 | -keep-internal 163 |
  • 164 |
  • 165 | -lang 166 |
  • 167 |
  • 168 | -cache 169 |
  • 170 |
171 | Improvements 172 |
    173 |
  • 174 | Added tests for inline functions 175 |
  • 176 |
  • 177 | Added test_include_preamble section of the XML-descriptor 178 |
  • 179 |
  • 180 | Added test_defines section of the XML-descriptor 181 |
  • 182 |
  • 183 | Improved design of test cases viewer 184 |
  • 185 |
  • 186 | Support for OpenBSD 187 |
  • 188 |
189 | Bug Fixes 190 |
    191 |
  • 192 | More accurate list of includes in test cases 193 |
  • 194 |
  • 195 | Corrected auto-generated sub-class declarations 196 |
  • 197 |
  • 198 | Corrected Makefile to install modules 199 |
  • 200 |
  • 201 | Other fixes 202 |
  • 203 |
204 | Other 205 |
    206 |
  • 207 | Code cleaning and refactoring 208 |
  • 209 |
210 |
211 | 212 | Version 1.12.11 (December 14, 2012)
213 | Improvements 214 |
    215 |
  • 216 | Support for Mac OS X 10.8 217 |
  • 218 |
219 | Bug Fixes 220 |
    221 |
  • 222 | Corrected generating of tests for protected methods 223 |
  • 224 |
  • 225 | Disabled tests for WEAK symbols 226 |
  • 227 |
  • 228 | Corrected Makefile 229 |
  • 230 |
  • 231 | Other fixes 232 |
  • 233 |
234 | Other 235 |
    236 |
  • 237 | Code cleaning 238 |
  • 239 |
240 |
241 | 242 | Version 1.12.5 (June 03, 2011)
243 | New Features 244 |
    245 |
  • 246 | Support for the latest GCC 4.6.0 247 |
  • 248 |
249 | Bug Fixes 250 |
    251 |
  • 252 | Corrected automatic include paths for headers 253 |
  • 254 |
  • 255 | Corrected template type names 256 |
  • 257 |
  • 258 | Corrected automatic preamble and finalization 259 |
  • 260 |
  • 261 | Corrected links in the problem summary 262 |
  • 263 |
  • 264 | Corrected help message and documentation 265 |
  • 266 |
  • 267 | Support for C-headers containing C++ keywords 268 |
  • 269 |
  • 270 | Corrected design of test viewer 271 |
  • 272 |
273 | Other 274 |
    275 |
  • 276 | Code cleaning 277 |
  • 278 |
279 |
280 | 281 | Version 1.12 (March 03, 2011)
282 | New Features 283 |
    284 |
  • 285 | Ported to Mac OS X (10.5) and MS Windows (Xp, Vista, 7) 286 |
  • 287 |
  • 288 | Improved performance 289 |
  • 290 |
  • 291 | Using File::Temp for storing temporary files 292 |
  • 293 |
  • 294 | Implemented universal library descriptor: you can specify a directory with headers and shared objects or comma separated list of headers and shared objects instead of a standard XML-descriptor 295 |
  • 296 |
  • 297 | Extended help message 298 |
  • 299 |
  • 300 | Added -info option to show full information about the tool 301 |
  • 302 |
  • 303 | Added -strict-* options family 304 |
  • 305 |
  • 306 | Added -debug option for debugging 307 |
  • 308 |
  • 309 | Added "param_name" associating section to specialized types 310 |
  • 311 |
  • 312 | Added -vnum option to specify library version number outside the descriptor 313 |
  • 314 |
  • 315 | Added "defines" section of the XML-descriptor to add defines at the headers parsing stage 316 |
  • 317 |
  • 318 | Added documentation: Options.html, Descriptor.html 319 |
  • 320 |
321 | Bug Fixes 322 |
    323 |
  • 324 | Corrected automatic detection of include paths for headers (-I options to GCC) 325 |
  • 326 |
  • 327 | Option -without-shared-objects has been renamed to -headers-only 328 |
  • 329 |
  • 330 | Corrected parsing of header files, identifying of some previously missed classes 331 |
  • 332 |
  • 333 | Documentation has been moved to "doc/" subdirectory 334 |
  • 335 |
336 |
337 | 338 | Version 1.11.1 (March 03, 2011)
339 | New Features 340 |
    341 |
  • 342 | Added documentation: README.html, CHANGES.html, SPECTYPE.html 343 |
  • 344 |
345 | Bug Fixes 346 |
    347 |
  • 348 | Corrected processing of typedef type names, fixed potential program hangup 349 |
  • 350 |
  • 351 | Corrected processing of special symbols in file paths specified by XML-descriptor ("+" and others) 352 |
  • 353 |
354 |
355 | 356 | Version 1.11 (July 22, 2010)
357 | New Features 358 |
    359 |
  • 360 | Added "skip_libs" section of the library descriptor: this section contains a list of shared objects and/or directories with shared objects that should not be processed 361 |
  • 362 |
  • 363 | Added -library-full-name option to display full library name in title of the report 364 |
  • 365 |
  • 366 | Improved performance on big libraries 367 |
  • 368 |
  • 369 | Improved unit tests code 370 |
  • 371 |
372 |
373 | 374 | Version 1.10 (June 25, 2010)
375 | New Features 376 |
    377 |
  • 378 | Added -relpath option: replace {RELPATH} in the library descriptor to some relative path 379 |
  • 380 |
  • 381 | Added "add_include_paths" section of the library descriptor: this section contains a list of include paths that should be added to the list of automatically detected include paths 382 |
  • 383 |
  • 384 | Improved initializing sequences in the test scenarios 385 |
  • 386 |
387 | Bug Fixes 388 |
    389 |
  • 390 | Corrected techniques for auto-detection of header file dependencies (include paths) 391 |
  • 392 |
  • 393 | Corrected checking of complex namespaces changes (C++) 394 |
  • 395 |
  • 396 | Corrected reuse of previously created variables in tests 397 |
  • 398 |
399 |
400 | 401 | Version 1.9 (June 08, 2010)
402 | New Features 403 |
    404 |
  • 405 | Added -params option for improving tests by adding parameter names separately from header files 406 |
  • 407 |
  • 408 | Added -header option for restricting a list of functions that should be tested by providing a header file name in which they are declared 409 |
  • 410 |
  • 411 | Added "skip_warnings" section to the library descriptor for skipping some test messages 412 |
  • 413 |
  • 414 | Separated stderr and stdout streams of the tool 415 |
  • 416 |
  • 417 | Improved tests generating rate 418 |
  • 419 |
  • 420 | Treating SEGV|FPE|BUS|ILL|PIPE|SYS|XCPU|XFSZ signals as errors in the report, other as warnings 421 |
  • 422 |
  • 423 | Improved test data generation 424 |
  • 425 |
426 | Bug Fixes 427 |
    428 |
  • 429 | Corrected complex array type names 430 |
  • 431 |
  • 432 | Corrected techniques for auto-detection of undefined symbols in the shared objects 433 |
  • 434 |
  • 435 | Corrected techniques for auto-detection of out parameters 436 |
  • 437 |
  • 438 | Corrected list of included headers 439 |
  • 440 |
  • 441 | Fixed tool hanging on some C++ headers (with many namespaces) 442 |
  • 443 |
  • 444 | Corrected order of preamble/finalization in the code 445 |
  • 446 |
  • 447 | Corrected initialization of agc/argv parameters 448 |
  • 449 |
  • 450 | Corrected initialization of big arrays 451 |
  • 452 |
  • 453 | Removed recursive calls from the tests code 454 |
  • 455 |
  • 456 | Corrected initialization of structure members 457 |
  • 458 |
  • 459 | Corrected initialization of struct/union types 460 |
  • 461 |
  • 462 | Corrected global_code/init_code/final_code/value parsing techniques 463 |
  • 464 |
  • 465 | Corrected tests cleaning 466 |
  • 467 |
468 |
469 | 470 | Version 1.8 (May 05, 2010)
471 | New Features 472 |
    473 |
  • 474 | Ignoring hidden .svn, .git, .bzr, .hg, and CVS directories 475 |
  • 476 |
  • 477 | Added -dumpversion option for printing tool version and don't do anything else 478 |
  • 479 |
  • 480 | Added "out_params" section to the library descriptor 481 |
  • 482 |
  • 483 | Added "lib_version" section to the specialized type and to the collection of specialized types. It allows to specify library version(s) the specialized type or collection will be applied to 484 |
  • 485 |
  • 486 | Improved techniques for auto-detection of out parameters 487 |
  • 488 |
  • 489 | Improved header files sorting for protecting from compilation errors on the intermediate phase of temporary header file compilation 490 |
  • 491 |
  • 492 | Improved techniques for auto-detection of header file dependencies (include paths) 493 |
  • 494 |
  • 495 | Extended set of tested interfaces 496 |
  • 497 |
  • 498 | Improved techniques for auto-detection of undefined symbols in the specified shared objects 499 |
  • 500 |
  • 501 | Calling of library malloc function instead of standard malloc() 502 |
  • 503 |
  • 504 | Improved techniques for initializing intrinsic types 505 |
  • 506 |
  • 507 | Added sentinel to function call (if needed) 508 |
  • 509 |
  • 510 | Treating receiving of ABRT signals and exit codes as warnings 511 |
  • 512 |
  • 513 | Added prefixes to header file includes in the test cases 514 |
  • 515 |
516 | Bug Fixes 517 |
    518 |
  • 519 | Test cases for some previously missed C++ namespaces 520 |
  • 521 |
  • 522 | Removed hidden "void const** __vtt_parm" parameters from the signature of some constructors 523 |
  • 524 |
  • 525 | Corrected redefinition of pure virtual destructors 526 |
  • 527 |
  • 528 | Corrected processing of several environment specialized types 529 |
  • 530 |
  • 531 | Corrected selection of functions to call for initializing parameters of other functions 532 |
  • 533 |
  • 534 | Corrected code parsing techniques (for "value" section of the specialized type) 535 |
  • 536 |
  • 537 | Preventing hanged execution of the tool on big arrays (>1024 elements) 538 |
  • 539 |
  • 540 | Corrected processing of "final_code" of specialized type for return value 541 |
  • 542 |
  • 543 | Corrected list of header file includes in the test cases 544 |
  • 545 |
  • 546 | Corrected processing of command line options 547 |
  • 548 |
549 |
550 | 551 | Version 1.7 (March 26, 2010)
552 | New Features 553 |
    554 |
  • 555 | The license was changed to dual GNU GPL and LGPL 556 |
  • 557 |
  • 558 | Added "pre_condition" and "post_condition" properties in the specialized types. Obsolete "constraint" property will be supported, but should be replaced by "post_condition" in the new code 559 |
  • 560 |
  • 561 | Added -splint-specs option for using splint annotations in the headers (@returned@, @out@, @notnull@, @requires@ and @ensures@) 562 |
  • 563 |
  • 564 | Using of throw() in the tests for C++ methods with the exceptions handling 565 |
  • 566 |
  • 567 | Changed meaning of the "skip_interfaces" section in the descriptor. Now it defines interfaces that should not be called in the tests 568 |
  • 569 |
  • 570 | Added "skip_headers" section in the descriptor 571 |
  • 572 |
573 | Bug Fixes 574 |
    575 |
  • 576 | Corrected processing of "libs_depend" section in the descriptor 577 |
  • 578 |
  • 579 | Directory with temporary files renamed from "temp" to hidden ".tmp_dir" 580 |
  • 581 |
  • 582 | Corrected processing of shared object dependencies 583 |
  • 584 |
  • 585 | Corrected processing of relative paths in the "headers", "include_paths", "libs" and "libs_depend" sections of the descriptor 586 |
  • 587 |
  • 588 | Added tests for some previously missed functions and conversion operators in C++ 589 |
  • 590 |
  • 591 | Improved internal test suite 592 |
  • 593 |
  • 594 | Corrected usage of the out-parameters 595 |
  • 596 |
  • 597 | Corrected code alignment 598 |
  • 599 |
  • 600 | Corrected LIBS variable in the makefiles 601 |
  • 602 |
  • 603 | Corrected enumeration members selecting 604 |
  • 605 |
  • 606 | Corrected some error messages 607 |
  • 608 |
609 |
610 | 611 | Version 1.6 (March 03, 2010)
612 | New Features 613 |
    614 |
  • 615 | Ported to FreeBSD and Haiku 616 |
  • 617 |
  • 618 | Added namespaces usage in the tests 619 |
  • 620 |
  • 621 | More accurate distinguishing pointer arguments *x and arrays x[] 622 |
  • 623 |
  • 624 | Added log for describing tool actions and occurred errors 625 |
  • 626 |
  • 627 | Improved techniques for auto-detection of header file dependencies (include paths) 628 |
  • 629 |
  • 630 | Added "libs" attribute to the specialized type for describing external libraries used by this type 631 |
  • 632 |
  • 633 | Added check for gcc/g++ version (>=3.0.0) 634 |
  • 635 |
  • 636 | Added -view-only option 637 |
  • 638 |
  • 639 | Added arguments to the tests 640 |
  • 641 |
  • 642 | More accurate detection of default gcc include paths 643 |
  • 644 |
  • 645 | Improved internal test suite 646 |
  • 647 |
  • 648 | Added error code on return 649 |
  • 650 |
651 | Bug Fixes 652 |
    653 |
  • 654 | Corrected signal handling 655 |
  • 656 |
  • 657 | Corrected header include lists 658 |
  • 659 |
  • 660 | Corrected makefiles 661 |
  • 662 |
  • 663 | Corrected usage of the out-parameters 664 |
  • 665 |
  • 666 | Corrected styles in the report design 667 |
  • 668 |
  • 669 | Corrected error messages 670 |
  • 671 |
  • 672 | Corrected code highlighting 673 |
  • 674 |
675 |
676 | 677 | Version 1.5 (February 15, 2010)
678 | New Features 679 |
    680 |
  • 681 | Added "libs_depend" section of the descriptor for shared objects that should be provided to GCC for resolving undefined symbols (if NEEDED elf section in the library shared objects doesn't include it) 682 |
  • 683 |
  • 684 | Added techniques for auto-detection of undefined symbols in the specified shared objects 685 |
  • 686 |
687 | Bug Fixes 688 |
    689 |
  • 690 | Corrected processing of header files in the /usr/include directory 691 |
  • 692 |
  • 693 | Corrected header include lists 694 |
  • 695 |
  • 696 | Corrected makefiles 697 |
  • 698 |
  • 699 | Corrected template for the collection of specialized types 700 |
  • 701 |
  • 702 | Corrected processing of tab characters in the descriptor 703 |
  • 704 |
  • 705 | Corrected usage of the out-parameters and return values 706 |
  • 707 |
  • 708 | Corrected alignment and highlighting of specialized type code 709 |
  • 710 |
  • 711 | Corrected parameters provided to X virtual frame buffer (xvfb) 712 |
  • 713 |
714 |
715 | 716 | Version 1.4 (February 04, 2010)
717 | New Features 718 |
    719 |
  • 720 | Automated detecting of header file dependencies. Now providing of "include_paths" section in the descriptor is not necessary 721 |
  • 722 |
  • 723 | Added template for the collection of specialized types (-specialized-type-template option) 724 |
  • 725 |
  • 726 | Optimized execution time 727 |
  • 728 |
729 | Bug Fixes 730 |
    731 |
  • 732 | Corrected makefiles 733 |
  • 734 |
  • 735 | Corrected descriptor template 736 |
  • 737 |
  • 738 | More appropriate usage of the out-parameters 739 |
  • 740 |
  • 741 | Corrected header include lists 742 |
  • 743 |
  • 744 | Corrected classes hierarchy in C 745 |
  • 746 |
747 |
748 | 749 | Version 1.3 (January 29, 2010)
750 | New Features 751 |
    752 |
  • 753 | Added -t2c option for generating tests in the Template2Code format 754 |
  • 755 |
  • 756 | Improved overall tests structure. Removed unnecessary code. More appropriate usage of the out-parameters. Improved makefiles code 757 |
  • 758 |
  • 759 | Added -without-shared-objects option for running the tool without providing of shared objects. It is necessary if the library contains in-line functions only and has no shared objects 760 |
  • 761 |
  • 762 | Added "libgroup" section in the descriptor for dividing the library into groups 763 |
  • 764 |
  • 765 | Added -isolated option to restrict functions usage in the tests by the lists specified by the -functions-list option or by the group division in the descriptor 766 |
  • 767 |
  • 768 | Tool has been ported to the Cygwin 769 |
  • 770 |
  • 771 | Using of constants (defines) for initializing parameters 772 |
  • 773 |
  • 774 | Added printing of incorrect return/parameter values to the report (intrinsic types only) 775 |
  • 776 |
  • 777 | Added -clean option for cleaning the tests 778 |
  • 779 |
780 | Bug Fixes 781 |
    782 |
  • 783 | Corrected help message 784 |
  • 785 |
  • 786 | Corrected highlighting of the code defines in the reports 787 |
  • 788 |
  • 789 | Corrected type conversion algorithms 790 |
  • 791 |
  • 792 | Corrected variables reusing for initializing parameters 793 |
  • 794 |
  • 795 | Corrected variables naming in the code of specialized types 796 |
  • 797 |
  • 798 | Corrected reusing of specialized type attributes for the out-parameters 799 |
  • 800 |
  • 801 | Corrected statements (REQ, REQva) for checking requirements in the generated code 802 |
  • 803 |
  • 804 | Corrected selection of functions to call for initializing parameters 805 |
  • 806 |
  • 807 | Corrected headers include list at the beginning of tests 808 |
  • 809 |
810 |
811 | 812 | Version 1.2 (December 22, 2009)
813 | New Features 814 |
    815 |
  • 816 | New sections "Warnings" and "Unexpected Output" in the report 817 |
  • 818 |
  • 819 | Random test generation mode improved (random selecting of enumeration members and values for intrinsic types) 820 |
  • 821 |
  • 822 | More accurate selecting of functions to call for initializing parameters of other functions 823 |
  • 824 |
  • 825 | Added names to unnamed parameters by analyzing type names 826 |
  • 827 |
  • 828 | Initialization of subclasses in C (if there are no other ways to initialize structure type) 829 |
  • 830 |
  • 831 | More accurate initializing of array types 832 |
  • 833 |
  • 834 | More accurate selecting of enumeration members 835 |
  • 836 |
  • 837 | More accurate type conversion algorithms 838 |
  • 839 |
  • 840 | Test data improved (added *.xml and *.dtd files) 841 |
  • 842 |
  • 843 | Values set for intrinsic types extended 844 |
  • 845 |
846 | Bug Fixes 847 |
    848 |
  • 849 | Corrected highlighting of variables in the report 850 |
  • 851 |
  • 852 | Corrected parsing of "interfaces" sub-section (in the "associating" section) in the collection of specialized types 853 |
  • 854 |
855 |
856 | 857 | Version 1.1 (December 04, 2009)
858 | New Features 859 |
    860 |
  • 861 | Inserting elements in the lists (C++ only) 862 |
  • 863 |
  • 864 | More accurate selecting of functions to call for initializing parameters 865 |
  • 866 |
  • 867 | More information about detected errors in the report 868 |
  • 869 |
  • 870 | New help message 871 |
  • 872 |
  • 873 | Additional warnings 874 |
  • 875 |
876 | Bug Fixes 877 |
    878 |
  • 879 | Corrected initialization of typedefs to intrinsic types 880 |
  • 881 |
  • 882 | Corrected headers include list at the beginning of tests 883 |
  • 884 |
  • 885 | Corrected sorting of detected problems in the report 886 |
  • 887 |
888 |
889 | 890 | Version 1.0 (November 30, 2009)
891 | Initial version of the tool. 892 |
893 | 894 | 897 | 898 |
899 |
900 | 901 |
902 | 903 | 904 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | --------------------------------------------------------------------------------