Tue Aug 26 10:18:02 2008 Google Inc. <opensource@google.com>

* cmockery: initial release:
	  A lightweight library to simplify and generalize the process of 
	  writing unit tests for C applications.


git-svn-id: http://cmockery.googlecode.com/svn/trunk@3 40f4469a-5155-0410-be90-2de3f0bae501
This commit is contained in:
stewartamiles 2008-08-26 17:51:56 +00:00
parent 1e8d7abef1
commit e414597c71
63 changed files with 49120 additions and 0 deletions

2
AUTHORS Normal file
View File

@ -0,0 +1,2 @@
opensource@google.com

28
COPYING Normal file
View File

@ -0,0 +1,28 @@
Copyright (c) 2006, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

5
ChangeLog Normal file
View File

@ -0,0 +1,5 @@
Tue Aug 26 10:18:02 2008 Google Inc. <opensource@google.com>
* cmockery: initial release:
A lightweight library to simplify and generalize the process of
writing unit tests for C applications.

230
INSTALL Normal file
View File

@ -0,0 +1,230 @@
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

117
Makefile.am Normal file
View File

@ -0,0 +1,117 @@
## This is a boilerplate file for Google opensource projects.
## To make it useful, replace <<TEXT>> with actual text for your project.
## Also, look at comments with "## double hashes" to see if any are worth
## uncommenting or modifying.
## Process this file with automake to produce Makefile.in
# Make sure that when we re-make ./configure, we get the macros we need
ACLOCAL_AMFLAGS = -I `pwd`/../autoconf
# This is so we can #include <google/foo>
AM_CPPFLAGS = -I$(top_srcdir)/src
# These are good warnings to turn on by default
if GCC
AM_CXXFLAGS = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
endif
googleincludedir = $(includedir)/google
## The .h files you want to install (that is, .h files that people
## who install this package can include in their own applications.)
googleinclude_HEADERS = src/google/cmockery.h
docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
## This is for HTML and other documentation you want to install.
## Add your documentation files (in doc/) in addition to these
## top-level boilerplate files. Also add a TODO file if you have one.
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README doc/index.html
## The libraries (.so's) you want to install
lib_LTLIBRARIES =
## unittests you want to run when people type 'make check'.
## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
## but it only seems to take effect for *binary* unittests (argh!)
TESTS =
TESTS_ENVIRONMENT = CMOCKERY_ROOTDIR = $(top_srcdir)
check_SCRIPTS =
# Every time you add a unittest to check_SCRIPTS, add it here too
noinst_SCRIPTS =
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
lib_LTLIBRARIES += libcmockery.la
libcmockery_la_SOURCES = src/config.h src/cmockery.c src/google/cmockery.h
libcmockery_la_CFLAGS = -Isrc/google
noinst_PROGRAMS = calculator
calculator_SOURCES = src/example/calculator.c src/config.h
calculator_CFLAGS =
unit_test_CFLAGS = -Isrc/google -Isrc/example -DUNIT_TESTING=1
noinst_PROGRAMS += calculator_test
calculator_test_SOURCES = src/example/calculator_test.c \
$(calculator_SOURCES)
calculator_test_CFLAGS = $(unit_test_CFLAGS)
calculator_test_LDADD = libcmockery.la
noinst_PROGRAMS += allocate_module_test
allocate_module_test_SOURCES = src/example/allocate_module_test.c \
src/example/allocate_module.c
allocate_module_test_CFLAGS = $(unit_test_CFLAGS)
allocate_module_test_LDADD = libcmockery.la
noinst_PROGRAMS += assert_macro_test
assert_macro_test_SOURCES = src/example/assert_macro_test.c \
src/example/assert_macro.c
assert_macro_test_CFLAGS = $(unit_test_CFLAGS)
assert_macro_test_LDADD = libcmockery.la
noinst_PROGRAMS += customer_database_test
customer_database_test_SOURCES = src/example/customer_database_test.c \
src/example/customer_database.c \
src/example/database.h
customer_database_test_CFLAGS = $(unit_test_CFLAGS)
customer_database_test_LDADD = libcmockery.la
noinst_PROGRAMS += key_value_test
key_value_test_SOURCES = src/example/key_value_test.c \
src/example/key_value.c
key_value_test_CFLAGS = $(unit_test_CFLAGS)
key_value_test_LDADD = libcmockery.la
noinst_PROGRAMS += product_database_test
product_database_testdir = src/example
product_database_test_SOURCES = src/example/product_database_test.c \
src/example/product_database.c \
src/example/database.h
product_database_test_CFLAGS = $(unit_test_CFLAGS)
product_database_test_LDADD = libcmockery.la
noinst_PROGRAMS += run_tests
run_tests_SOURCES = src/example/run_tests.c
run_tests_CFLAGS = $(unit_test_CFLAGS)
run_tests_LDADD = libcmockery.la
## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
## This should always include $(TESTS), but may also include other
## binaries that you compile but don't want automatically installed.
noinst_PROGRAMS += $(TESTS)
rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
deb: dist-gzip packages/deb.sh packages/deb/*
@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
## If you're using libtool, add 'libtool' here. Also add this rule:
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
libtool $(SCRIPTS)

1086
Makefile.in Normal file

File diff suppressed because it is too large Load Diff

0
NEWS Normal file
View File

10
README Normal file
View File

@ -0,0 +1,10 @@
For information about how to use the cmockery unit testing framework see
doc/index.html.
COMPILING
---------
To compile the cmockery library and example applications run ./configure
followed by make. On Windows from the command line run vsvars.bat then cd into
the windows subdirectory of this project and run nmake.
This code has been tested on Linux (Ubuntu) and Windows using VC++7 and VC++8.

7352
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

55
autogen.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/sh
# Before using, you should figure out all the .m4 macros that your
# configure.m4 script needs and make sure they exist in the autoconf/
# directory.
#
# These are the files that this script might edit:
# aclocal.m4 configure Makefile.in src/config.h.in \
# depcomp config.guess config.sub install-sh missing mkinstalldirs \
# ltmain.sh
#
# Here's a command you can run to see what files aclocal will import:
# aclocal -I ../autoconf --output=- | sed -n 's/^m4_include..\([^]]*\).*/\1/p'
set -ex
rm -rf autom4te.cache
trap 'rm -f aclocal.m4.tmp' EXIT
# Use version 1.9 of aclocal and automake if available.
ACLOCAL=aclocal-1.9
if test -z `which "$ACLOCAL"`; then
ACLOCAL=aclocal
fi
AUTOMAKE=automake-1.9
if test -z `which "$AUTOMAKE"`; then
AUTOMAKE=automake
fi
# glibtoolize is used for Mac OS X
LIBTOOLIZE=libtoolize
if test -z `which "$LIBTOOLIZE"`; then
LIBTOOLIZE=glibtoolize
fi
# aclocal tries to overwrite aclocal.m4 even if the contents haven't
# changed, which is annoying when the file is not open for edit (in
# p4). We work around this by writing to a temp file and just
# updating the timestamp if the file hasn't change.
"$ACLOCAL" --force -I m4 --output=aclocal.m4.tmp
if cmp aclocal.m4.tmp aclocal.m4; then
touch aclocal.m4 # pretend that we regenerated the file
rm -f aclocal.m4.tmp
else
mv aclocal.m4.tmp aclocal.m4 # we did set -e above, so we die if this fails
fi
grep -q LIBTOOL configure.ac && "$LIBTOOLIZE" -c -f
autoconf -f -W all,no-obsolete
autoheader -f -W all
"$AUTOMAKE" -a -c -f -W all
rm -rf autom4te.cache
exit 0

99
compile Executable file
View File

@ -0,0 +1,99 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
# Copyright 1999, 2000 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Usage:
# compile PROGRAM [ARGS]...
# `-o FOO.o' is removed from the args passed to the actual compile.
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status

1466
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1579
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

23296
configure vendored Executable file

File diff suppressed because it is too large Load Diff

69
configure.ac Normal file
View File

@ -0,0 +1,69 @@
## This is a boilerplate file for Google opensource projects.
## To make it useful, replace <<TEXT>> with actual text for your project.
## Also, look at comments with "## double hashes" to see if any are worth
## uncommenting or modifying.
## Process this file with autoconf to produce configure.
## In general, the safest way to proceed is to run ./autogen.sh
# make sure we're interpreted by some minimal autoconf
AC_PREREQ(2.57)
AC_INIT(cmockery, 0.1, opensource@google.com)
# The argument here is just something that should be in the current directory
# (for sanity checking)
AC_CONFIG_SRCDIR(README)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(src/config.h)
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc
# Uncomment this if you'll be exporting libraries (.so's)
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
# Check whether some low-level functions/files are available
AC_HEADER_STDC
# Here are some examples of how to check for the existence of a fn or file
##AC_CHECK_FUNCS(memmove)
##AC_CHECK_HEADERS(sys/resource.h)
AC_CHECK_FUNCS(setjmp)
AC_CHECK_FUNCS(longjmp)
AC_CHECK_FUNCS(strcmp)
AC_CHECK_FUNCS(strcpy)
AC_CHECK_FUNCS(memcpy)
AC_CHECK_FUNCS(memset)
AC_CHECK_FUNCS(malloc)
AC_CHECK_FUNCS(calloc)
AC_CHECK_FUNCS(free)
AC_CHECK_FUNCS(exit)
AC_CHECK_FUNCS(signal)
AC_CHECK_FUNCS(printf)
AC_CHECK_FUNCS(fprintf)
AC_CHECK_FUNCS(snprintf)
AC_CHECK_FUNCS(vsnprintf)
AC_CHECK_HEADERS(assert.h)
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_HEADERS(setjmp.h)
AC_CHECK_HEADERS(stdarg.h)
AC_CHECK_HEADERS(stddef.h)
AC_CHECK_HEADERS(stdio.h)
AC_CHECK_HEADERS(stdlib.h)
AC_CHECK_HEADERS(string.h)
AC_CHECK_HEADERS(signal.h)
# Find out what namespace 'normal' STL code lives in, and also what namespace
# the user wants our classes to be defined in
AC_CXX_STL_NAMESPACE
AC_DEFINE_GOOGLE_NAMESPACE(google)
## Check out ../autoconf/ for other macros you can call to do useful stuff
# Write generated configuration file
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

530
depcomp Executable file
View File

@ -0,0 +1,530 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2005-07-09.11
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mecanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

718
doc/index.html Normal file
View File

@ -0,0 +1,718 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html><head>
<title>Cmockery</title>
</head>
<body>
<h1>Cmockery Unit Testing Framework</h1>
<p>Cmockery is a lightweight library that is used to author C unit tests.</p>
<ul>Contents
<li><a href="#Motivation">Motivation</a></li>
<li><a href="#Overview">Overview</a></li>
<li><a href="#TestExecution">Test Execution</a>
<li><a href="#ExceptionHandling">Exception Handling</a></li>
<li><a href="#FailureConditions">Failure Conditions</a></li>
<li><a href="#Assertions">Assertions</a></li>
<ul>
<li><a href="#AssertMacros">Assert Macros</a></li>
</ul>
<li><a href="#MemoryAllocation">Dynamic Memory Allocation</a></li>
<li><a href="#MockFunctions">Mock functions</a></li>
<ul>
<li><a href="#MockFunctionsReturnValues">Return Values</a></li>
<li><a href="#MockFunctionsCheckingParameters">Checking Parameters</a></li>
</ul>
<li><a href="#TestState">Test State</a></li>
<li><a href="#Example">Example</a></li>
</ul>
<a name="Motivation"><h2>Motivation</h2></a>
<p>There are a variety of C unit testing frameworks available however many of
them are fairly complex and require the latest compiler technology. Some
development requires the use of old compilers which makes it difficult to
use some unit testing frameworks. In addition many unit testing frameworks
assume the code being tested is an application or module that is targeted to
the same platform that will ultimately execute the test. Because of this
assumption many frameworks require the inclusion of standard C library headers
in the code module being tested which may collide with the custom or
incomplete implementation of the C library utilized by the code under test.</p>
<p>Cmockery only requires a test application is linked with the standard C
library which minimizes conflicts with standard C library headers. Also,
Cmockery tries avoid the use of some of the newer features of C compilers.</p>
<p>This results in Cmockery being a relatively small library that can be used
to test a variety of exotic code. If a developer wishes to simply test an
application with the latest compiler then other unit testing frameworks maybe
preferable.</p>
<a name="Overview"><h2>Overview</h2></a>
<p>Cmockery tests are compiled into stand-alone executables and linked with
the Cmockery library, the standard C library and module being tested. Any
symbols external to the module being tested should be mocked - replaced with
functions that return values determined by the test - within the test
application. Even though significant differences may exist between the target
execution environment of a code module and the environment used to test the
code the unit testing is still valid since its goal is to test the logic of a
code modules at a functional level and not necessarily all of its interactions
with the target execution environment.</p>
<p>It may not be possible to compile a module into a test application without
some modification, therefore the preprocessor symbol <b>UNIT_TESTING</b> should
be defined when Cmockery unit test applications are compiled so code within the
module can be conditionally compiled for tests.</p>
<a name="TestExecution"><h2>Test Execution</h2></a>
<p>Cmockery unit test cases are functions with the signature
<b>void function(void **state)</b>. Cmockery test applications initialize a
table with test case function pointers using <b>unit_test*()</b> macros. This
table is then passed to the <b>run_tests()</b> macro to execute the tests.
<b>run_tests()</b> sets up the appropriate exception / signal handlers and
other data structures prior to running each test function. When a unit test
is complete <b>run_tests()</b> performs various checks to determine whether
the test succeeded.</p>
<h4>Using run_tests()</h4>
<listing>
<a href="../src/example/run_tests.c">run_tests.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
// A test case that does nothing and succeeds.
void null_test_success(void **state) {
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(null_test_success),
};
return run_tests(tests);
}
</listing>
<a name="ExceptionHandling"><h2>Exception Handling</h2></a>
<p>Before a test function is executed by <b>run_tests()</b>,
exception / signal handlers are overridden with a handler that simply
displays an error and exits a test function if an exception occurs. If an
exception occurs outside of a test function, for example in Cmockery itself,
the application aborts execution and returns an error code.</p>
<a name="FailureConditions"><h2>Failure Conditions</h2></a>
<p>If a failure occurs during a test function that's executed via
<b>run_tests()</b>, the test function is aborted and the application's
execution resumes with the next test function.
Test failures are ultimately signalled via the Cmockery function <b>fail()</b>.
The following events will result in the Cmockery library signalling a test
failure...
<ul>
<li><a href="#Assertions">Assertions</a></li>
<li><a href="#ExceptionHandling">Exceptions</a></li>
<li><a href="#MemoryAllocation">Memory leaks</a></li>
<li><a href="#TestState">Mismatched setup and tear down functions</a></li>
<li><a href="#MockFunctionsReturnValues">Missing mock return values</a></li>
<li><a href="#MockFunctionsReturnValues">Unused mock return values</a></li>
<li><a href="#MockFunctionsCheckingParameters">Missing expected parameter
values</a></li>
<li><a href="#MockFunctionsCheckingParameters">Unused expected parameter
values</a></li>
</ul>
</p>
<a name="Assertions"><h2>Assertions</h2></a>
<p>Runtime assert macros like the standard C library's <b>assert()</b> should
be redefined in modules being tested to use Cmockery's <b>mock_assert()</b>
function. Normally <b>mock_assert()</b> signals a
<a href="#FailureConditions">test failure</a>. If a function is called using
the <b>expect_assert_failure()</b> macro, any calls to <b>mock_assert()</b>
within the function will result in the execution of the test. If no
calls to <b>mock_assert()</b> occur during the function called via
<b>expect_assert_failure()</b> a test failure is signalled.</p>
<h4>Using mock_assert()</h4>
<listing>
<a href="../src/example/assert_module.c">assert_module.c</a>
-------------------------------------------------------------------------------
#include &lt;assert.h&gt;
// If unit testing is enabled override assert with mock_assert().
#if UNIT_TESTING
extern void mock_assert(const int result, const char* const expression,
const char * const file, const int line);
#undef assert
#define assert(expression) \
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
#endif // UNIT_TESTING
void increment_value(int * const value) {
assert(value);
(*value) ++;
}
void decrement_value(int * const value) {
if (value) {
*value --;
}
}
<a href="../src/example/assert_module_test.c">assert_module_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
extern void increment_value(int * const value);
/* This test case will fail but the assert is caught by run_tests() and the
* next test is executed. */
void increment_value_fail(void **state) {
increment_value(NULL);
}
// This test case succeeds since increment_value() asserts on the NULL pointer.
void increment_value_assert(void **state) {
expect_assert_failure(increment_value(NULL));
}
/* This test case fails since decrement_value() doesn't assert on a NULL
* pointer. */
void decrement_value_fail(void **state) {
expect_assert_failure(decrement_value(NULL));
}
int main(int argc, char *argv[]) {
const UnitTest tests[] = {
unit_test(increment_value_fail),
unit_test(increment_value_assert),
unit_test(decrement_value_fail),
};
return run_tests(tests);
}
</listing>
<h3><a name="AssertMacros">Assert Macros</a></h3>
<p>Cmockery provides an assortment of assert macros that tests applications
should use use in preference to the C standard library's assert macro. On an
assertion failure a Cmockery assert macro will write the failure to the
standard error stream and signal a test failure. Due to limitations of the
C language the general C standard library assert() and Cmockery's
assert_true() and assert_false() macros can only display the expression that
caused the assert failure. Cmockery's type specific assert macros,
assert_{type}_equal() and assert_{type}_not_equal(), display the data that
caused the assertion failure which increases data visibility aiding
debugging of failing test cases.</p>
<h4>Using assert_{type}_equal() macros</h4>
<listing>
<a href="../src/example/assert_macro.c">assert_macro.c</a>
-------------------------------------------------------------------------------
#include &lt;string.h&gt;
static const char* status_code_strings[] = {
"Address not found",
"Connection dropped",
"Connection timed out",
};
const char* get_status_code_string(const unsigned int status_code) {
return status_code_strings[status_code];
};
unsigned int string_to_status_code(const char* const status_code_string) {
unsigned int i;
for (i = 0; i < sizeof(status_code_string) / sizeof(status_code_string[0]);
i++) {
if (strcmp(status_code_strings[i], status_code_string) == 0) {
return i;
}
}
return ~0U;
}
<a href="../src/example/assert_macro_test.c">assert_macro_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
extern const char* get_status_code_string(const unsigned int status_code);
extern unsigned int string_to_status_code(
const char* const status_code_string);
/* This test will fail since the string returned by get_status_code_string(0)
* doesn't match "Connection timed out". */
void get_status_code_string_test(void **state) {
assert_string_equal(get_status_code_string(0), "Address not found");
assert_string_equal(get_status_code_string(1), "Connection timed out");
}
// This test will fail since the status code of "Connection timed out" isn't 1
void string_to_status_code_test(void **state) {
assert_int_equal(string_to_status_code("Address not found"), 0);
assert_int_equal(string_to_status_code("Connection timed out"), 1);
}
int main(int argc, char *argv[]) {
const UnitTest tests[] = {
unit_test(get_status_code_string_test),
unit_test(string_to_status_code_test),
};
return run_tests(tests);
}
</listing>
<a name="MemoryAllocation"><h2>Dynamic Memory Allocation</h2></a>
<p>To test for memory leaks, buffer overflows and underflows a module being
tested by Cmockery should replace calls to <b>malloc()</b>, <b>calloc()</b> and
<b>free()</b> to <b>test_malloc()</b>, <b>test_calloc()</b> and
<b>test_free()</b> respectively. Each time a block is deallocated using
<b>test_free()</b> it is checked for corruption, if a corrupt block is found
a <a href="#FailureConditions">test failure</a> is signalled. All blocks
allocated using the <b>test_*()</b> allocation functions are tracked by the
Cmockery library. When a test completes if any allocated blocks (memory leaks)
remain they are reported and a test failure is signalled.</p>
<p>For simplicity Cmockery currently executes all tests in one process.
Therefore all test cases in a test application share a single address space
which means memory corruption from a single test case could potentially cause
the test application to exit prematurely.</p>
<h4>Using Cmockery's Allocators</h4>
<listing>
<a href="../src/example/allocate_module.c">allocate_module.c</a>
-------------------------------------------------------------------------------
#include &lt;malloc.h&gt;
#if UNIT_TESTING
extern void* _test_malloc(const size_t size, const char* file, const int line);
extern void* _test_calloc(const size_t number_of_elements, const size_t size,
const char* file, const int line);
extern void _test_free(void* const ptr, const char* file, const int line);
#define malloc(size) _test_malloc(size, __FILE__, __LINE__)
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
#define free(ptr) _test_free(ptr, __FILE__, __LINE__)
#endif // UNIT_TESTING
void leak_memory() {
int * const temporary = (int*)malloc(sizeof(int));
*temporary = 0;
}
void buffer_overflow() {
char * const memory = (char*)malloc(sizeof(int));
memory[sizeof(int)] = '!';
free(memory);
}
void buffer_underflow() {
char * const memory = (char*)malloc(sizeof(int));
memory[-1] = '!';
free(memory);
}
<a href="../src/example/allocate_module_test.c">allocate_module_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
extern void leak_memory();
extern void buffer_overflow();
extern void buffer_underflow();
// Test case that fails as leak_memory() leaks a dynamically allocated block.
void leak_memory_test(void **state) {
leak_memory();
}
// Test case that fails as buffer_overflow() corrupts an allocated block.
void buffer_overflow_test(void **state) {
buffer_overflow();
}
// Test case that fails as buffer_underflow() corrupts an allocated block.
void buffer_underflow_test(void **state) {
buffer_underflow();
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(leak_memory_test),
unit_test(buffer_overflow_test),
unit_test(buffer_underflow_test),
};
return run_tests(tests);
}
</listing>
<a name="MockFunctions"><h2>Mock Functions</h2></a>
<p>A unit test should ideally isolate the function or module being tested
from any external dependencies. This can be performed using mock functions
that are either statically or dynamically linked with the module being tested.
Mock functions must be statically linked when the code being tested directly
references external functions. Dynamic linking is simply the process of
setting a function pointer in a table used by the tested module to reference
a mock function defined in the unit test.</p>
<a name="MockFunctionsReturnValues"><h3>Return Values</h3></a>
<p>In order to simplify the implementation of mock functions Cmockery provides
functionality which stores return values for mock functions in each test
case using <b>will_return()</b>. These values are then returned by each mock
function using calls to <b>mock()</b>.
Values passed to <b>will_return()</b> are added to a queue for each function
specified. Each successive call to <b>mock()</b> from a function removes a
return value from the queue. This makes it possible for a mock function to use
multiple calls to <b>mock()</b> to return output parameters in addition to a
return value. In addition this allows the specification of return values for
multiple calls to a mock function.</p>
<h4>Using will_return()</h4>
<listing>
<a name="../src/example/database.h" href="database.h">database.h</a>
-------------------------------------------------------------------------------
typedef struct DatabaseConnection DatabaseConnection;
/* Function that takes an SQL query string and sets results to an array of
* pointers with the result of the query. The value returned specifies the
* number of items in the returned array of results. The returned array of
* results are statically allocated and should not be deallocated using free()
*/
typedef unsigned int (*QueryDatabase)(
DatabaseConnection* const connection, const char * const query_string,
void *** const results);
// Connection to a database.
struct DatabaseConnection {
const char *url;
unsigned int port;
QueryDatabase query_database;
};
// Connect to a database.
DatabaseConnection* connect_to_database(const char * const url,
const unsigned int port);
<a href="../src/example/customer_database.c">customer_database.c</a>
-------------------------------------------------------------------------------
#include &lt;stddef.h&gt;
#include &lt;stdio.h&gt;
#include <a href="#database.h">&lt;database.h&gt;</a>
#ifdef _WIN32
#define snprintf _snprintf
#endif // _WIN32
// Connect to the database containing customer information.
DatabaseConnection* connect_to_customer_database() {
return connect_to_database("customers.abcd.org", 321);
}
/* Find the ID of a customer by his/her name returning a value > 0 if
* successful, 0 otherwise. */
unsigned int get_customer_id_by_name(
DatabaseConnection * const connection,
const char * const customer_name) {
char query_string[256];
int number_of_results;
void **results;
snprintf(query_string, sizeof(query_string),
"SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name);
number_of_results = connection->query_database(connection, query_string,
&results);
if (number_of_results != 1) {
return -1;
}
return (unsigned int)results[0];
}
<a href="../src/example/customer_database_test.c">customer_database_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
#include <a href="#database.h">&lt;database.h&gt;</a>
extern DatabaseConnection* connect_to_customer_database();
extern unsigned int get_customer_id_by_name(
DatabaseConnection * const connection, const char * const customer_name);
// Mock query database function.
unsigned int mock_query_database(
DatabaseConnection* const connection, const char * const query_string,
void *** const results) {
*results = (void**)mock();
return (unsigned int)mock();
}
// Mock of the connect to database function.
DatabaseConnection* connect_to_database(const char * const database_url,
const unsigned int port) {
return (DatabaseConnection*)mock();
}
void test_connect_to_customer_database(void **state) {
will_return(connect_to_database, 0x0DA7ABA53);
assert_true(connect_to_customer_database() ==
(DatabaseConnection*)0x0DA7ABA53);
}
/* This test fails as the mock function connect_to_database() will have no
* value to return. */
void fail_connect_to_customer_database(void **state) {
will_return(connect_to_database, 0x0DA7ABA53);
assert_true(connect_to_customer_database() ==
(DatabaseConnection*)0x0DA7ABA53);
}
void test_get_customer_id_by_name(void **state) {
DatabaseConnection connection = {
"somedatabase.somewhere.com", 12345678, mock_query_database
};
// Return a single customer ID when mock_query_database() is called.
int customer_ids = 543;
will_return(mock_query_database, &customer_ids);
will_return(mock_query_database, 1);
assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543);
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(test_connect_to_customer_database),
unit_test(fail_connect_to_customer_database),
unit_test(test_get_customer_id_by_name),
};
return run_tests(tests);
}
</listing>
<a name="MockFunctionsCheckingParameters"><h3>Checking Parameters</h3></a>
<p>In addition to storing the return values of mock functions, Cmockery
provides functionality to store expected values for mock function parameters
using the expect_*() functions provided. A mock function parameter can then
be validated using the check_expected() macro.
<p>Successive calls to expect_*() macros for a parameter queues values to
check the specified parameter. check_expected() checks a function parameter
against the next value queued using expect_*(), if the parameter check fails a
test failure is signalled. In addition if check_expected() is called and
no more parameter values are queued a test failure occurs.</p>
<h4>Using expect_*()</h4>
<listing>
<a href="../src/example/product_database.c">product_database.c</a>
-------------------------------------------------------------------------------
#include <a href="#database.h">&lt;database.h&gt;</a>
// Connect to the database containing customer information.
DatabaseConnection* connect_to_product_database() {
return connect_to_database("products.abcd.org", 322);
}
<a href="../src/example/product_database_test.c">product_database_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;cmockery.h&gt;
#include <a href="#database.h">&lt;database.h&gt;</a>
extern DatabaseConnection* connect_to_product_database();
/* Mock connect to database function.
* NOTE: This mock function is very general could be shared between tests
* that use the imaginary database.h module. */
DatabaseConnection* connect_to_database(const char * const url,
const unsigned int port) {
check_expected(url);
check_expected(port);
return (DatabaseConnection*)mock();
}
void test_connect_to_product_database(void **state) {
expect_string(connect_to_database, url, "products.abcd.org");
expect_value(connect_to_database, port, 322);
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal(connect_to_product_database(), 0xDA7ABA53);
}
/* This test will fail since the expected URL is different to the URL that is
* passed to connect_to_database() by connect_to_product_database(). */
void test_connect_to_product_database_bad_url(void **state) {
expect_string(connect_to_database, url, "products.abcd.com");
expect_value(connect_to_database, port, 322);
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
}
/* This test will fail since the mock connect_to_database() will attempt to
* retrieve a value for the parameter port which isn't specified by this
* test function. */
void test_connect_to_product_database_missing_parameter(void **state) {
expect_string(connect_to_database, url, "products.abcd.org");
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(test_connect_to_product_database),
unit_test(test_connect_to_product_database_bad_url),
unit_test(test_connect_to_product_database_missing_parameter),
};
return run_tests(tests);
}
</listing>
<a name="TestState"><h2>Test State</h2></a>
<p>Cmockery allows the specification of multiple setup and tear down functions
for each test case. Setup functions, specified by the <b>unit_test_setup()</b>
or <b>unit_test_setup_teardown()</b> macros allow common initialization to be
shared between multiple test cases. In addition, tear down functions,
specified by the <b>unit_test_teardown()</b> or
<b>unit_test_setup_teardown()</b> macros provide a code path that is always
executed for a test case even when it fails.</p>
<h4>Using unit_test_setup_teardown()</h4>
<listing>
<a href="../src/example/key_value.c">key_value.c</a>
-------------------------------------------------------------------------------
#include &lt;stddef.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
typedef struct KeyValue {
unsigned int key;
const char* value;
} KeyValue;
static KeyValue *key_values = NULL;
static unsigned int number_of_key_values = 0;
void set_key_values(KeyValue * const new_key_values,
const unsigned int new_number_of_key_values) {
key_values = new_key_values;
number_of_key_values = new_number_of_key_values;
}
// Compare two key members of KeyValue structures.
int key_value_compare_keys(const void *a, const void *b) {
return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key;
}
// Search an array of key value pairs for the item with the specified value.
KeyValue* find_item_by_value(const char * const value) {
unsigned int i;
for (i = 0; i < number_of_key_values; i++) {
if (strcmp(key_values[i].value, value) == 0) {
return &key_values[i];
}
}
return NULL;
}
// Sort an array of key value pairs by key.
void sort_items_by_key() {
qsort(key_values, number_of_key_values, sizeof(*key_values),
key_value_compare_keys);
}
<a href="../src/example/key_value_test.c">key_value_test.c</a>
-------------------------------------------------------------------------------
#include &lt;stdarg.h&gt;
#include &lt;stddef.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;string.h&gt;
#include &lt;cmockery.h&gt;
/* This is duplicated here from the module setup_teardown.c to reduce the
* number of files used in this test. */
typedef struct KeyValue {
unsigned int key;
const char* value;
} KeyValue;
void set_key_values(KeyValue * const new_key_values,
const unsigned int new_number_of_key_values);
extern KeyValue* find_item_by_value(const char * const value);
extern void sort_items_by_key();
static KeyValue key_values[] = {
{ 10, "this" },
{ 52, "test" },
{ 20, "a" },
{ 13, "is" },
};
void create_key_values(void **state) {
KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values));
memcpy(items, key_values, sizeof(key_values));
*state = (void*)items;
set_key_values(items, sizeof(key_values) / sizeof(key_values[0]));
}
void destroy_key_values(void **state) {
test_free(*state);
set_key_values(NULL, 0);
}
void test_find_item_by_value(void **state) {
unsigned int i;
for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
KeyValue * const found = find_item_by_value(key_values[i].value);
assert_true(found);
assert_int_equal(found->key, key_values[i].key);
assert_string_equal(found->value, key_values[i].value);
}
}
void test_sort_items_by_key(void **state) {
unsigned int i;
KeyValue * const kv = *state;
sort_items_by_key();
for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
assert_true(kv[i - 1].key < kv[i].key);
}
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test_setup_teardown(test_find_item_by_value, create_key_values,
destroy_key_values),
unit_test_setup_teardown(test_sort_items_by_key, create_key_values,
destroy_key_values),
};
return run_tests(tests);
}
</listing>
<a name="Example"><h2>Example</h2></a>
<p>A small command line calculator
<a href="../src/example/calculator.c">calculator.c</a> application
and test application that full exercises the calculator application
<a href="../src/example/calculator_test.c">calculator_test.c</a>
are provided as an example of Cmockery's features discussed in this document.
</p>
<hr>
<address></address>
<!-- hhmts start --> Last modified: Tue Aug 26 09:33:31 PDT 2008 <!-- hhmts end -->
</body> </html>

323
install-sh Executable file
View File

@ -0,0 +1,323 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-05-14.22
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

6908
ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

16
m4/ac_have_attribute.m4 Normal file
View File

@ -0,0 +1,16 @@
AC_DEFUN([AX_C___ATTRIBUTE__], [
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(ac_cv___attribute__, [
AC_TRY_COMPILE(
[#include <stdlib.h>
static void foo(void) __attribute__ ((unused));
void foo(void) { exit(1); }],
[],
ac_cv___attribute__=yes,
ac_cv___attribute__=no
)])
if test "$ac_cv___attribute__" = "yes"; then
AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
fi
AC_MSG_RESULT($ac_cv___attribute__)
])

31
m4/ac_rwlock.m4 Normal file
View File

@ -0,0 +1,31 @@
# TODO(csilvers): it would be better to actually try to link against
# -pthreads, to make sure it defines these methods, but that may be
# too hard, since pthread support is really tricky.
# Check for support for pthread_rwlock_init() etc.
# These aren't posix, but are widely supported. To get them on linux,
# you need to define _XOPEN_SOURCE first, so this check assumes your
# application does that.
#
# Note: OS X (as of 6/1/06) seems to support pthread_rwlock, but
# doesn't define PTHREAD_RWLOCK_INITIALIZER. Therefore, we don't test
# that particularly macro. It's probably best if you don't use that
# macro in your code either.
AC_DEFUN([AC_RWLOCK],
[AC_CACHE_CHECK(support for pthread_rwlock_* functions,
ac_rwlock,
[AC_LANG_SAVE
AC_LANG_C
AC_TRY_COMPILE([#define _XOPEN_SOURCE 500
#include <pthread.h>],
[pthread_rwlock_t l; pthread_rwlock_init(&l, NULL);
pthread_rwlock_rdlock(&l);
return 0;],
ac_rwlock=yes, ac_rwlock=no)
AC_LANG_RESTORE
])
if test "$ac_rwlock" = yes; then
AC_DEFINE(HAVE_RWLOCK,1,[define if the compiler implements pthread_rwlock_*])
fi
])

363
m4/acx_pthread.m4 Normal file
View File

@ -0,0 +1,363 @@
# This was retrieved from
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
# See also (perhaps for new versions?)
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
#
# We've rewritten the inconsistency check code (from avahi), to work
# more broadly. In particular, it no longer assumes ld accepts -zdefs.
# This caused a restructing of the code, but the functionality has only
# changed a little.
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl @summary figure out how to build C programs using POSIX threads
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2006-05-29
dnl @license GPLWithACException
dnl
dnl Checks for GCC shared/pthread inconsistency based on work by
dnl Marcin Owsiany <marcin@owsiany.pl>
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
# The next part tries to detect GCC inconsistency with -shared on some
# architectures and systems. The problem is that in certain
# configurations, when -shared is specified, GCC "forgets" to
# internally use various flags which are still necessary.
#
# Prepare the flags
#
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
save_CC="$CC"
# Try with the flags determined by the earlier checks.
#
# -Wl,-z,defs forces link-time symbol resolution, so that the
# linking checks with -shared actually have any value
#
# FIXME: -fPIC is required for -shared on many architectures,
# so we specify it here, but the right way would probably be to
# properly detect whether it is actually required.
CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CC="$PTHREAD_CC"
# In order not to create several levels of indentation, we test
# the value of "$done" until we find the cure or run out of ideas.
done="no"
# First, make sure the CFLAGS we added are actually accepted by our
# compiler. If not (and OS X's ld, for instance, does not accept -z),
# then we can't do this test.
if test x"$done" = xno; then
AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
AC_TRY_LINK(,, , [done=yes])
if test "x$done" = xyes ; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
fi
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
#
# Linux gcc on some architectures such as mips/mipsel forgets
# about -lpthread
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lpthread fixes that])
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
#
# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lc_r fixes that])
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
if test x"$done" = xno; then
# OK, we have run out of ideas
AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
# so it's not safe to assume that we may use pthreads
acx_pthread_ok=no
fi
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD

View File

@ -0,0 +1,24 @@
# Check compiler characteristics (e.g. type sizes, PRIxx macros, ...)
# If types $1 and $2 are compatible, perform action $3
AC_DEFUN([AC_TYPES_COMPATIBLE],
[AC_TRY_COMPILE([#include <stddef.h>], [$1 v1 = 0; $2 v2 = 0; return (&v1 - &v2)], $3)])
define(AC_PRIUS_COMMENT, [printf format code for printing a size_t and ssize_t])
AC_DEFUN([AC_COMPILER_CHARACTERISTICS],
[AC_CACHE_CHECK(AC_PRIUS_COMMENT, ac_cv_formatting_prius_prefix,
[AC_TYPES_COMPATIBLE(unsigned int, size_t,
ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1)
AC_TYPES_COMPATIBLE(unsigned long, size_t,
ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1)
AC_TYPES_COMPATIBLE(unsigned long long, size_t,
ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1
)])
if test -z "$ac_cv_formatting_prius_defined"; then
ac_cv_formatting_prius_prefix=z;
fi
AC_DEFINE_UNQUOTED(PRIuS, "${ac_cv_formatting_prius_prefix}u", AC_PRIUS_COMMENT)
AC_DEFINE_UNQUOTED(PRIxS, "${ac_cv_formatting_prius_prefix}x", AC_PRIUS_COMMENT)
AC_DEFINE_UNQUOTED(PRIdS, "${ac_cv_formatting_prius_prefix}d", AC_PRIUS_COMMENT)
])

42
m4/google_namespace.m4 Normal file
View File

@ -0,0 +1,42 @@
# Allow users to override the namespace we define our application's classes in
# Arg $1 is the default namespace to use if --enable-namespace isn't present.
# In general, $1 should be 'google', so we put all our exported symbols in a
# unique namespace that is not likely to conflict with anyone else. However,
# when it makes sense -- for instance, when publishing stl-like code -- you
# may want to go with a different default, like 'std'.
# We guarantee the invariant that GOOGLE_NAMESPACE starts with ::,
# unless it's the empty string. Thus, it's always safe to do
# GOOGLE_NAMESPACE::foo and be sure you're getting the foo that's
# actually in the google namespace, and not some other namespace that
# the namespace rules might kick in.
AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
[google_namespace_default=[$1]
AC_ARG_ENABLE(namespace, [ --enable-namespace=FOO to define these Google
classes in the FOO namespace. --disable-namespace
to define them in the global namespace. Default
is to define them in namespace $1.],
[case "$enableval" in
yes) google_namespace="$google_namespace_default" ;;
no) google_namespace="" ;;
*) google_namespace="$enableval" ;;
esac],
[google_namespace="$google_namespace_default"])
if test -n "$google_namespace"; then
ac_google_namespace="::$google_namespace"
ac_google_start_namespace="namespace $google_namespace {"
ac_google_end_namespace="}"
else
ac_google_namespace=""
ac_google_start_namespace=""
ac_google_end_namespace=""
fi
AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
Namespace for Google classes)
AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
Puts following code inside the Google namespace)
AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_, $ac_google_end_namespace,
Stops putting the code inside the Google namespace)
])

15
m4/namespaces.m4 Normal file
View File

@ -0,0 +1,15 @@
# Checks whether the compiler implements namespaces
AC_DEFUN([AC_CXX_NAMESPACES],
[AC_CACHE_CHECK(whether the compiler implements namespaces,
ac_cv_cxx_namespaces,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([namespace Outer {
namespace Inner { int i = 0; }}],
[using namespace Outer::Inner; return i;],
ac_cv_cxx_namespaces=yes,
ac_cv_cxx_namespaces=no)
AC_LANG_RESTORE])
if test "$ac_cv_cxx_namespaces" = yes; then
AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
fi])

44
m4/stl_hash.m4 Normal file
View File

@ -0,0 +1,44 @@
# We check two things: where the include file is for hash_map, and
# what namespace hash_map lives in within that include file. We
# include AC_TRY_COMPILE for all the combinations we've seen in the
# wild. We define one of HAVE_HASH_MAP or HAVE_EXT_HASH_MAP depending
# on location, and HASH_NAMESPACE to be the namespace hash_map is
# defined in.
#
# Ideally we'd use AC_CACHE_CHECK, but that only lets us store one value
# at a time, and we need to store two (filename and namespace).
# prints messages itself, so we have to do the message-printing ourselves
# via AC_MSG_CHECKING + AC_MSG_RESULT. (TODO(csilvers): can we cache?)
AC_DEFUN([AC_CXX_STL_HASH],
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_MSG_CHECKING(the location of hash_map)
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cv_cxx_hash_map=""
for location in ext/hash_map hash_map; do
for namespace in __gnu_cxx "" std stdext; do
if test -z "$ac_cv_cxx_hash_map"; then
AC_TRY_COMPILE([#include <$location>],
[${namespace}::hash_map<int, int> t],
[ac_cv_cxx_hash_map="<$location>";
ac_cv_cxx_hash_namespace="$namespace";])
fi
done
done
ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
if test -n "$ac_cv_cxx_hash_map"; then
AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map])
AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set])
AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map,
[the location of <hash_map>])
AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set,
[the location of <hash_set>])
AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
[the namespace of hash_map/hash_set])
AC_MSG_RESULT([$ac_cv_cxx_hash_map])
else
AC_MSG_RESULT()
AC_MSG_WARN([could not find an STL hash_map])
fi
])

25
m4/stl_namespace.m4 Normal file
View File

@ -0,0 +1,25 @@
# We check what namespace stl code like vector expects to be executed in
AC_DEFUN([AC_CXX_STL_NAMESPACE],
[AC_CACHE_CHECK(
what namespace STL code is in,
ac_cv_cxx_stl_namespace,
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <vector>],
[vector<int> t; return 0;],
ac_cv_cxx_stl_namespace=none)
AC_TRY_COMPILE([#include <vector>],
[std::vector<int> t; return 0;],
ac_cv_cxx_stl_namespace=std)
AC_LANG_RESTORE])
if test "$ac_cv_cxx_stl_namespace" = none; then
AC_DEFINE(STL_NAMESPACE,,
[the namespace where STL code like vector<> is defined])
fi
if test "$ac_cv_cxx_stl_namespace" = std; then
AC_DEFINE(STL_NAMESPACE,std,
[the namespace where STL code like vector<> is defined])
fi
])

360
missing Executable file
View File

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

158
mkinstalldirs Executable file
View File

@ -0,0 +1,158 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2005-06-29.22
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
errstatus=0
dirmode=
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
for d
do
test "x$d" = x && continue
pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp=$pathcomp/
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

70
packages/deb.sh Executable file
View File

@ -0,0 +1,70 @@
#!/bin/bash -e
# This takes one commandline argument, the name of the package. If no
# name is given, then we'll end up just using the name associated with
# an arbitrary .tar.gz file in the rootdir. That's fine: there's probably
# only one.
#
# Run this from the 'packages' directory, just under rootdir
## Set LIB to lib if exporting a library, empty-string else
LIB=
#LIB=lib
PACKAGE="$1"
# We can only build Debian packages, if the Debian build tools are installed
if [ \! -x /usr/bin/debuild ]; then
echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2
exit 0
fi
# Double-check we're in the packages directory, just under rootdir
if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then
echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
echo "Also, you must run \"make dist\" before running this script." 1>&2
exit 0
fi
# Find the top directory for this package
topdir="${PWD%/*}"
# Find the tar archive built by "make dist"
archive="$(basename "$(ls -1 ${topdir}/$PACKAGE*.tar.gz | tail -n 1)" .tar.gz)"
if [ -z "${archive}" ]; then
echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2
exit 0
fi
# Create a pristine directory for building the Debian package files
trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM
rm -rf tmp
mkdir -p tmp
cd tmp
# Debian has very specific requirements about the naming of build
# directories, and tar archives. It also wants to write all generated
# packages to the parent of the source directory. We accommodate these
# requirements by building directly from the tar file.
ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive}.orig.tar.gz"
tar zfx "${LIB}${archive}.orig.tar.gz"
[ -n "${LIB}" ] && mv "${archive}" "${LIB}${archive}"
cd "${LIB}${archive}"
# This is one of those 'specific requirements': where the deb control files live
ln -s "packages/deb" "debian"
# Now, we can call Debian's standard build tool
debuild -uc -us
cd ../.. # get back to the original top-level dir
# We'll put the result in a subdirectory that's named after the OS version
# we've made this .deb file for.
destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)"
rm -rf "$destdir"
mkdir -p "$destdir"
mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir"
echo
echo "The Debian package files are located in $PWD/$destdir"

7
packages/deb/README Normal file
View File

@ -0,0 +1,7 @@
The list of files here isn't complete. For a step-by-step guide on
how to set this package up correctly, check out
http://www.debian.org/doc/maint-guide/
Most of the files that are in this directory are boilerplate.
However, you may need to change the list of binary-arch dependencies
in 'rules'.

5
packages/deb/changelog Normal file
View File

@ -0,0 +1,5 @@
cmockery (0.1-1) unstable; urgency=low
* Initial release.
-- Google Inc. <opensource@google.com> Mon, 28 Aug 2008 17:43:20 -0700

1
packages/deb/compat Normal file
View File

@ -0,0 +1 @@
4

20
packages/deb/control Normal file
View File

@ -0,0 +1,20 @@
Source: cmockery
Section: libdevel
Priority: optional
Maintainer: Google Inc, <opensource@google.com>
Build-Depends: debhelper (>= 4.0.0), binutils
Standards-Version: 3.6.1
Package: libcmockery-dev
Section: libdevel
Architecture: any
Depends: libcmockery0 (= ${Source-Version})
Description: The cmockery package contains a lightweight library to simplify
and generalize the process of writing unit tests for C applications.
Package: libcmockery0
Section: libs
Architecture: any
Description: The cmockery package contains static and debug libraries and
header files for the development of test applications using %name.

35
packages/deb/copyright Normal file
View File

@ -0,0 +1,35 @@
This package was debianized by Google Inc. <opensource@google.com> on
28 August 2008.
It was downloaded from http://code.google.com/
Upstream Author: opensource@google.com
Copyright (c) 2006, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
packages/deb/docs Normal file
View File

@ -0,0 +1,7 @@
AUTHORS
COPYING
ChangeLog
INSTALL
NEWS
README
doc/index.html

View File

@ -0,0 +1,4 @@
usr/lib
usr/include
usr/include/google

View File

@ -0,0 +1,9 @@
usr/include/google/*
usr/lib/lib*.so
usr/lib/lib*.a
usr/lib/lib*.la
debian/tmp/usr/include/google/*
debian/tmp/usr/lib/lib*.so
debian/tmp/usr/lib/lib*.a
debian/tmp/usr/lib/lib*.la

View File

@ -0,0 +1 @@
usr/lib

View File

@ -0,0 +1,2 @@
usr/lib/lib*.so.*
debian/tmp/usr/lib/lib*.so.*

117
packages/deb/rules Executable file
View File

@ -0,0 +1,117 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
# shared library versions, option 1
#version=2.0.5
#major=2
# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
version=`ls src/.libs/lib*.so.* | \
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
major=`ls src/.libs/lib*.so.* | \
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
config.status: configure
dh_testdir
# Add here commands to configure the package.
CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/tmp
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs ChangeLog
dh_installdocs
dh_installexamples
dh_install --sourcedir=debian/tmp
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

75
packages/rpm.sh Executable file
View File

@ -0,0 +1,75 @@
#!/bin/sh -e
# Run this from the 'packages' directory, just under rootdir
# We can only build rpm packages, if the rpm build tools are installed
if [ \! -x /usr/bin/rpmbuild ]
then
echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2
exit 0
fi
# Check the commandline flags
PACKAGE="$1"
VERSION="$2"
fullname="${PACKAGE}-${VERSION}"
archive=../$fullname.tar.gz
if [ -z "$1" -o -z "$2" ]
then
echo "Usage: $0 <package name> <package version>" 1>&2
exit 0
fi
# Double-check we're in the packages directory, just under rootdir
if [ \! -r ../Makefile -a \! -r ../INSTALL ]
then
echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
echo "Also, you must run \"make dist\" before running this script." 1>&2
exit 0
fi
if [ \! -r "$archive" ]
then
echo "Cannot find $archive. Run \"make dist\" first." 1>&2
exit 0
fi
# Create the directory where the input lives, and where the output should live
RPM_SOURCE_DIR="/tmp/rpmsource-$fullname"
RPM_BUILD_DIR="/tmp/rpmbuild-$fullname"
trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM
rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR"
mkdir "$RPM_SOURCE_DIR"
mkdir "$RPM_BUILD_DIR"
cp "$archive" "$RPM_SOURCE_DIR"
rpmbuild -bb rpm/rpm.spec \
--define "NAME $PACKAGE" \
--define "VERSION $VERSION" \
--define "_sourcedir $RPM_SOURCE_DIR" \
--define "_builddir $RPM_BUILD_DIR" \
--define "_rpmdir $RPM_SOURCE_DIR"
# We put the output in a directory based on what system we've built for
destdir=rpm-unknown
if [ -r /etc/issue ]
then
grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7
grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8
grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9
if grep Fedora /etc/issue >/dev/null; then
destdir=fc`grep Fedora /etc/issue | cut -d' ' -f 4`;
fi
fi
rm -rf "$destdir"
mkdir -p "$destdir"
# We want to get not only the main package but devel etc, hence the middle *
mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir"
echo
echo "The rpm package file(s) are located in $PWD/$destdir"

76
packages/rpm/rpm.spec Normal file
View File

@ -0,0 +1,76 @@
## This is a boilerplate file for Google opensource projects.
## To make it useful, replace <<TEXT>> with actual text for your project.
## Also, look at comments with "## double hashes" to see if any are worth
## uncommenting or modifying.
%define RELEASE 1
%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
%define prefix /usr
Name: %NAME
Summary: Lightweight C unit testing framework.
Version: %VERSION
Release: %rel
Group: Development/Libraries
URL: http://code.google.com/p/cmockery
License: Apache
Vendor: Google
Packager: Google Inc. <opensource@google.com>
Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
Distribution: Redhat 7 and above.
Buildroot: %{_tmppath}/%{name}-root
Prefix: %prefix
%description
The %name package contains a lightweight library to simplify and generalize the
process of writing unit tests for C applications.
%package devel
Summary: Lightweight C unit testing framework.
Group: Development/Libraries
Requires: %{NAME} = %{VERSION}
%description devel
The %name package contains static and debug libraries and header files for the
development of test applications using %name.
%changelog
* Mon Aug 25 2008 <opensource@google.com>
- First draft
%prep
%setup
%build
./configure
make prefix=%prefix
%install
rm -rf $RPM_BUILD_ROOT
make prefix=$RPM_BUILD_ROOT%{prefix} install
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
## Mark all installed files within /usr/share/doc/{package name} as
## documentation. This depends on the following two lines appearing in
## Makefile.am:
## docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
## dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README
%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}
%{prefix}/share/doc/%{NAME}-%{VERSION}/*
%{prefix}/lib/libcmockery.so.0
%{prefix}/lib/libcmockery.so.0.0.0
%files devel
%defattr(-,root,root)
%{prefix}/include/google
%{prefix}/lib/libcmockery.a
%{prefix}/lib/libcmockery.la
%{prefix}/lib/libcmockery.so

1681
src/cmockery.c Executable file

File diff suppressed because it is too large Load Diff

136
src/config.h.in Normal file
View File

@ -0,0 +1,136 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Namespace for Google classes */
#undef GOOGLE_NAMESPACE
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define to 1 if you have the `calloc' function. */
#undef HAVE_CALLOC
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `exit' function. */
#undef HAVE_EXIT
/* Define to 1 if you have the `fprintf' function. */
#undef HAVE_FPRINTF
/* Define to 1 if you have the `free' function. */
#undef HAVE_FREE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `longjmp' function. */
#undef HAVE_LONGJMP
/* Define to 1 if you have the `malloc' function. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* define if the compiler implements namespaces */
#undef HAVE_NAMESPACES
/* Define to 1 if you have the `printf' function. */
#undef HAVE_PRINTF
/* Define to 1 if you have the `setjmp' function. */
#undef HAVE_SETJMP
/* Define to 1 if you have the <setjmp.h> header file. */
#undef HAVE_SETJMP_H
/* Define to 1 if you have the `signal' function. */
#undef HAVE_SIGNAL
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcmp' function. */
#undef HAVE_STRCMP
/* Define to 1 if you have the `strcpy' function. */
#undef HAVE_STRCPY
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* the namespace where STL code like vector<> is defined */
#undef STL_NAMESPACE
/* Version number of package */
#undef VERSION
/* Stops putting the code inside the Google namespace */
#undef _END_GOOGLE_NAMESPACE_
/* Puts following code inside the Google namespace */
#undef _START_GOOGLE_NAMESPACE_

View File

@ -0,0 +1,44 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <malloc.h>
#if UNIT_TESTING
extern void* _test_malloc(const size_t size, const char* file, const int line);
extern void* _test_calloc(const size_t number_of_elements, const size_t size,
const char* file, const int line);
extern void _test_free(void* const ptr, const char* file, const int line);
#define malloc(size) _test_malloc(size, __FILE__, __LINE__)
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
#define free(ptr) _test_free(ptr, __FILE__, __LINE__)
#endif // UNIT_TESTING
void leak_memory() {
int * const temporary = (int*)malloc(sizeof(int));
*temporary = 0;
}
void buffer_overflow() {
char * const memory = (char*)malloc(sizeof(int));
memory[sizeof(int)] = '!';
free(memory);
}
void buffer_underflow() {
char * const memory = (char*)malloc(sizeof(int));
memory[-1] = '!';
free(memory);
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
extern void leak_memory();
extern void buffer_overflow();
extern void buffer_underflow();
// Test case that fails as leak_memory() leaks a dynamically allocated block.
void leak_memory_test(void **state) {
leak_memory();
}
// Test case that fails as buffer_overflow() corrupts an allocated block.
void buffer_overflow_test(void **state) {
buffer_overflow();
}
// Test case that fails as buffer_underflow() corrupts an allocated block.
void buffer_underflow_test(void **state) {
buffer_underflow();
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(leak_memory_test),
unit_test(buffer_overflow_test),
unit_test(buffer_underflow_test),
};
return run_tests(tests);
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
static const char* status_code_strings[] = {
"Address not found",
"Connection dropped",
"Connection timed out",
};
const char* get_status_code_string(const unsigned int status_code) {
return status_code_strings[status_code];
};
unsigned int string_to_status_code(const char* const status_code_string) {
unsigned int i;
for (i = 0; i < sizeof(status_code_string) / sizeof(status_code_string[0]);
i++) {
if (strcmp(status_code_strings[i], status_code_string) == 0) {
return i;
}
}
return ~0U;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
extern const char* get_status_code_string(const unsigned int status_code);
extern unsigned int string_to_status_code(
const char* const status_code_string);
/* This test will fail since the string returned by get_status_code_string(0)
* doesn't match "Connection timed out". */
void get_status_code_string_test(void **state) {
assert_string_equal(get_status_code_string(0), "Address not found");
assert_string_equal(get_status_code_string(1), "Connection timed out");
}
// This test will fail since the status code of "Connection timed out" isn't 1
void string_to_status_code_test(void **state) {
assert_int_equal(string_to_status_code("Address not found"), 0);
assert_int_equal(string_to_status_code("Connection timed out"), 1);
}
int main(int argc, char *argv[]) {
const UnitTest tests[] = {
unit_test(get_status_code_string_test),
unit_test(string_to_status_code_test),
};
return run_tests(tests);
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
// If unit testing is enabled override assert with mock_assert().
#if UNIT_TESTING
extern void mock_assert(const int result, const char* const expression,
const char * const file, const int line);
#undef assert
#define assert(expression) \
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
#endif // UNIT_TESTING
void increment_value(int * const value) {
assert(value);
(*value) ++;
}
void decrement_value(int * const value) {
if (value) {
(*value) --;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
extern void increment_value(int * const value);
/* This test case will fail but the assert is caught by run_tests() and the
* next test is executed. */
void increment_value_fail(void **state) {
increment_value(NULL);
}
// This test case succeeds since increment_value() asserts on the NULL pointer.
void increment_value_assert(void **state) {
expect_assert_failure(increment_value(NULL));
}
/* This test case fails since decrement_value() doesn't assert on a NULL
* pointer. */
void decrement_value_fail(void **state) {
expect_assert_failure(decrement_value(NULL));
}
int main(int argc, char *argv[]) {
const UnitTest tests[] = {
unit_test(increment_value_fail),
unit_test(increment_value_assert),
unit_test(decrement_value_fail),
};
return run_tests(tests);
}

267
src/example/calculator.c Normal file
View File

@ -0,0 +1,267 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// A calculator example used to demonstrate the cmockery testing library.
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// If this is being built for a unit test.
#if UNIT_TESTING
/* Redirect printf to a function in the test application so it's possible to
* test the standard output. */
#ifdef printf
#undef printf
#endif // printf
#define printf example_test_printf
extern void print_message(const char *format, ...);
/* Redirect fprintf to a function in the test application so it's possible to
* test error messages. */
#ifdef fprintf
#undef fprintf
#endif // fprintf
#define fprintf example_test_fprintf
extern int example_test_fprintf(FILE * const file, const char *format, ...);
// Redirect assert to mock_assert() so assertions can be caught by cmockery.
#ifdef assert
#undef assert
#endif // assert
#define assert(expression) \
mock_assert((int)(expression), #expression, __FILE__, __LINE__)
void mock_assert(const int result, const char* expression, const char *file,
const int line);
/* Redirect calloc and free to test_calloc() and test_free() so cmockery can
* check for memory leaks. */
#ifdef calloc
#undef calloc
#endif // calloc
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
#ifdef free
#undef free
#endif // free
#define free(ptr) _test_free(ptr, __FILE__, __LINE__)
void* _test_calloc(const size_t number_of_elements, const size_t size,
const char* file, const int line);
void _test_free(void* const ptr, const char* file, const int line);
/* main is defined in the unit test so redefine name of the the main function
* here. */
#define main example_main
/* All functions in this object need to be exposed to the test application,
* so redefine static to nothing. */
#define static
#endif // UNIT_TESTING
// A binary arithmetic integer operation (add, subtract etc.)
typedef int (*BinaryOperator)(int a, int b);
// Structure which maps operator strings to functions.
typedef struct OperatorFunction {
const char* operator;
BinaryOperator function;
} OperatorFunction;
static int add(int a, int b);
static int subtract(int a, int b);
static int multiply(int a, int b);
static int divide(int a, int b);
// Associate operator strings to functions.
static OperatorFunction operator_function_map[] = {
{"+", add},
{"-", subtract},
{"*", multiply},
{"/", divide},
};
static int add(int a, int b) {
return a + b;
}
static int subtract(int a, int b) {
return a - b;
}
static int multiply(int a, int b) {
return a * b;
}
static int divide(int a, int b) {
assert(b); // Check for divde by zero.
return a / b;
}
/* Searches the specified array of operator_functions for the function
* associated with the specified operator_string. This function returns the
* function associated with operator_string if successful, NULL otherwise.
*/
static BinaryOperator find_operator_function_by_string(
const size_t number_of_operator_functions,
const OperatorFunction * const operator_functions,
const char* const operator_string) {
size_t i;
assert(!number_of_operator_functions || operator_functions);
assert(operator_string);
for (i = 0; i < number_of_operator_functions; i++) {
const OperatorFunction *const operator_function =
&operator_functions[i];
if (strcmp(operator_function->operator, operator_string) == 0) {
return operator_function->function;
}
}
return NULL;
}
/* Perform a series of binary arithmetic integer operations with no operator
* precedence.
*
* The input expression is specified by arguments which is an array of
* containing number_of_arguments strings. Operators invoked by the expression
* are specified by the array operator_functions containing
* number_of_operator_functions, OperatorFunction structures. The value of
* each binary operation is stored in a pointer returned to intermediate_values
* which is allocated by malloc().
*
* If successful, this function returns the integer result of the operations.
* If an error occurs while performing the operation error_occurred is set to
* 1, the operation is aborted and 0 is returned.
*/
static int perform_operation(
int number_of_arguments, char *arguments[],
const size_t number_of_operator_functions,
const OperatorFunction * const operator_functions,
int * const number_of_intermediate_values,
int ** const intermediate_values, int * const error_occurred) {
char *end_of_integer;
int value;
unsigned int i;
assert(!number_of_arguments || arguments);
assert(!number_of_operator_functions || operator_functions);
assert(error_occurred);
assert(number_of_intermediate_values);
assert(intermediate_values);
*error_occurred = 0;
*number_of_intermediate_values = 0;
*intermediate_values = NULL;
if (!number_of_arguments)
return 0;
// Parse the first value.
value = (int)strtol(arguments[0], &end_of_integer, 10);
if (end_of_integer == arguments[0]) {
// If an error occurred while parsing the integer.
fprintf(stderr, "Unable to parse integer from argument %s\n",
arguments[0]);
*error_occurred = 1;
return 0;
}
// Allocate an array for the output values.
*intermediate_values = calloc(((number_of_arguments - 1) / 2),
sizeof(**intermediate_values));
i = 1;
while (i < number_of_arguments) {
int other_value;
const char* const operator_string = arguments[i];
const BinaryOperator function = find_operator_function_by_string(
number_of_operator_functions, operator_functions, operator_string);
int * const intermediate_value =
&((*intermediate_values)[*number_of_intermediate_values]);
(*number_of_intermediate_values) ++;
if (!function) {
fprintf(stderr, "Unknown operator %s, argument %d\n",
operator_string, i);
*error_occurred = 1;
break;
}
i ++;
if (i == number_of_arguments) {
fprintf(stderr, "Binary operator %s missing argument\n",
operator_string);
*error_occurred = 1;
break;
}
other_value = (int)strtol(arguments[i], &end_of_integer, 10);
if (end_of_integer == arguments[i]) {
// If an error occurred while parsing the integer.
fprintf(stderr, "Unable to parse integer %s of argument %d\n",
arguments[i], i);
*error_occurred = 1;
break;
}
i ++;
// Perform the operation and store the intermediate value.
*intermediate_value = function(value, other_value);
value = *intermediate_value;
}
if (*error_occurred) {
free(*intermediate_values);
*intermediate_values = NULL;
*number_of_intermediate_values = 0;
return 0;
}
return value;
}
int main(int argc, char *argv[]) {
int return_value;
int number_of_intermediate_values;
int *intermediate_values;
// Peform the operation.
const int result = perform_operation(
argc - 1, &argv[1],
sizeof(operator_function_map) / sizeof(operator_function_map[0]),
operator_function_map, &number_of_intermediate_values,
&intermediate_values, &return_value);
// If no errors occurred display the result.
if (!return_value && argc > 1) {
unsigned int i;
unsigned int intermediate_value_index = 0;
printf("%s\n", argv[1]);
for (i = 2; i < argc; i += 2) {
assert(intermediate_value_index < number_of_intermediate_values);
printf(" %s %s = %d\n", argv[i], argv[i + 1],
intermediate_values[intermediate_value_index++]);
}
printf("= %d\n", result);
}
if (intermediate_values) {
free(intermediate_values);
}
return return_value;
}

View File

@ -0,0 +1,425 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include <stdio.h>
#ifdef _WIN32
// Compatibility with the Windows standard C library.
#define vsnprintf _vsnprintf
#endif // _WIN32
#define array_length(x) (sizeof(x) / sizeof((x)[0]))
/* To simplify this code, these functions and data structures could have been
* separated out from the application example.c into a header shared with
* test application. However, this example illustrates how it's possible to
* test existing code with little modification. */
typedef int (*BinaryOperator)(int a, int b);
typedef struct OperatorFunction {
const char* operator;
BinaryOperator function;
} OperatorFunction;
extern int add(int a, int b);
extern int subtract(int a, int b);
extern int multiply(int a, int b);
extern int divide(int a, int b);
extern BinaryOperator find_operator_function_by_string(
const size_t number_of_operator_functions,
const OperatorFunction * const operator_functions,
const char* const operator_string);
extern int perform_operation(
int number_of_arguments, char *arguments[],
const size_t number_of_operator_functions,
const OperatorFunction * const operator_functions,
int * const number_of_intermediate_values,
int ** const intermediate_values, int * const error_occurred);
extern int example_main(int argc, char *argv[]);
/* A mock fprintf function that checks the value of strings printed to the
* standard error stream. */
int example_test_fprintf(FILE* const file, const char *format, ...) {
int return_value;
va_list args;
char temporary_buffer[256];
assert_true(file == stderr);
va_start(args, format);
return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
format, args);
check_expected(temporary_buffer);
va_end(args);
return return_value;
}
/* A mock printf function that checks the value of strings printed to the
* standard output stream. */
int example_test_printf(const char *format, ...) {
int return_value;
va_list args;
char temporary_buffer[256];
va_start(args, format);
return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
format, args);
check_expected(temporary_buffer);
va_end(args);
return return_value;
}
// A mock binary operator function.
int binary_operator(int a, int b) {
check_expected(a);
check_expected(b);
return (int)mock();
}
// Ensure add() adds two integers correctly.
void test_add(void **state) {
assert_int_equal(add(3, 3), 6);
assert_int_equal(add(3, -3), 0);
}
// Ensure subtract() subtracts two integers correctly.
void test_subtract(void **state) {
assert_int_equal(subtract(3, 3), 0);
assert_int_equal(subtract(3, -3), 6);
}
// Ensure multiple() mulitplies two integers correctly.
void test_multiply(void **state) {
assert_int_equal(multiply(3, 3), 9);
assert_int_equal(multiply(3, 0), 0);
}
// Ensure divide() divides one integer by another correctly.
void test_divide(void **state) {
assert_int_equal(divide(10, 2), 5);
assert_int_equal(divide(2, 10), 0);
}
// Ensure divide() asserts when trying to divide by zero.
void test_divide_by_zero(void **state) {
expect_assert_failure(divide(100, 0));
}
/* Ensure find_operator_function_by_string() asserts when a NULL pointer is
* specified as the table to search. */
void test_find_operator_function_by_string_null_functions(void **state) {
expect_assert_failure(find_operator_function_by_string(1, NULL, "test"));
}
/* Ensure find_operator_function_by_string() asserts when a NULL pointer is
* specified as the string to search for. */
void test_find_operator_function_by_string_null_string(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
expect_assert_failure(find_operator_function_by_string(
array_length(operator_functions), operator_functions, NULL));
}
/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer
* is specified as the table to search when the table size is 0. */
void test_find_operator_function_by_string_valid_null_functions(void **state) {
assert_int_equal((int)find_operator_function_by_string(0, NULL, "test"),
(int)NULL);
}
/* Ensure find_operator_function_by_string() returns NULL when searching for
* an operator string that isn't in the specified table. */
void test_find_operator_function_by_string_not_found(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
{"-", binary_operator},
{"/", binary_operator},
};
assert_int_equal((int)find_operator_function_by_string(
array_length(operator_functions), operator_functions, "test"),
(int)NULL);
}
/* Ensure find_operator_function_by_string() returns the correct function when
* searching for an operator string that is in the specified table. */
void test_find_operator_function_by_string_found(void **state) {
const OperatorFunction operator_functions[] = {
{"+", (BinaryOperator)0x12345678},
{"-", (BinaryOperator)0xDEADBEEF},
{"/", (BinaryOperator)0xABADCAFE},
};
assert_int_equal((int)find_operator_function_by_string(
array_length(operator_functions), operator_functions, "-"),
0xDEADBEEF);
}
// Ensure perform_operation() asserts when a NULL arguments array is specified.
void test_perform_operation_null_args(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_assert_failure(perform_operation(
1, NULL, array_length(operator_functions), operator_functions,
&number_of_intermediate_values, &intermediate_values,
&error_occurred));
}
/* Ensure perform_operation() asserts when a NULL operator_functions array is
* specified. */
void test_perform_operation_null_operator_functions(void **state) {
char *args[] = {
"1", "+", "2", "*", "4"
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_assert_failure(perform_operation(
array_length(args), args, 1, NULL, &number_of_intermediate_values,
&intermediate_values, &error_occurred));
}
/* Ensure perform_operation() asserts when a NULL pointer is specified for
* number_of_intermediate_values. */
void test_perform_operation_null_number_of_intermediate_values(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"1", "+", "2", "*", "4"
};
int *intermediate_values;
int error_occurred;
expect_assert_failure(perform_operation(
array_length(args), args, 1, operator_functions, NULL,
&intermediate_values, &error_occurred));
}
/* Ensure perform_operation() asserts when a NULL pointer is specified for
* intermediate_values. */
void test_perform_operation_null_intermediate_values(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"1", "+", "2", "*", "4"
};
int number_of_intermediate_values;
int error_occurred;
expect_assert_failure(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values, NULL,
&error_occurred));
}
// Ensure perform_operation() returns 0 when no arguments are specified.
void test_perform_operation_no_arguments(void **state) {
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
assert_int_equal(perform_operation(
0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values,
&error_occurred), 0);
assert_int_equal(error_occurred, 0);
}
/* Ensure perform_operation() returns an error if the first argument isn't
* an integer string. */
void test_perform_operation_first_arg_not_integer(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"test", "+", "2", "*", "4"
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_string(example_test_fprintf, temporary_buffer,
"Unable to parse integer from argument test\n");
assert_int_equal(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values,
&intermediate_values, &error_occurred), 0);
assert_int_equal(error_occurred, 1);
}
/* Ensure perform_operation() returns an error when parsing an unknown
* operator. */
void test_perform_operation_unknown_operator(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"1", "*", "2", "*", "4"
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_string(example_test_fprintf, temporary_buffer,
"Unknown operator *, argument 1\n");
assert_int_equal(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values,
&intermediate_values, &error_occurred), 0);
assert_int_equal(error_occurred, 1);
}
/* Ensure perform_operation() returns an error when nothing follows an
* operator. */
void test_perform_operation_missing_argument(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"1", "+",
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_string(example_test_fprintf, temporary_buffer,
"Binary operator + missing argument\n");
assert_int_equal(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values,
&intermediate_values, &error_occurred), 0);
assert_int_equal(error_occurred, 1);
}
/* Ensure perform_operation() returns an error when an integer doesn't follow
* an operator. */
void test_perform_operation_no_integer_after_operator(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
};
char *args[] = {
"1", "+", "test",
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
expect_string(example_test_fprintf, temporary_buffer,
"Unable to parse integer test of argument 2\n");
assert_int_equal(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values,
&intermediate_values, &error_occurred), 0);
assert_int_equal(error_occurred, 1);
}
// Ensure perform_operation() succeeds given valid input parameters.
void test_perform_operation(void **state) {
const OperatorFunction operator_functions[] = {
{"+", binary_operator},
{"*", binary_operator},
};
char *args[] = {
"1", "+", "3", "*", "10",
};
int number_of_intermediate_values;
int *intermediate_values;
int error_occurred;
// Setup return values of mock operator functions.
// Addition.
expect_value(binary_operator, a, 1);
expect_value(binary_operator, b, 3);
will_return(binary_operator, 4);
// Multiplication.
expect_value(binary_operator, a, 4);
expect_value(binary_operator, b, 10);
will_return(binary_operator, 40);
assert_int_equal(perform_operation(
array_length(args), args, array_length(operator_functions),
operator_functions, &number_of_intermediate_values,
&intermediate_values, &error_occurred), 40);
assert_int_equal(error_occurred, 0);
assert_true(intermediate_values);
assert_int_equal(intermediate_values[0], 4);
assert_int_equal(intermediate_values[1], 40);
test_free(intermediate_values);
}
// Ensure main() in example.c succeeds given no arguments.
void test_example_main_no_args(void **state) {
char *args[] = {
"example",
};
assert_int_equal(example_main(array_length(args), args), 0);
}
// Ensure main() in example.c succeeds given valid input arguments.
void test_example_main(void **state) {
char *args[] = {
"example", "1", "+", "3", "*", "10",
};
expect_string(example_test_printf, temporary_buffer, "1\n");
expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n");
expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n");
expect_string(example_test_printf, temporary_buffer, "= 40\n");
assert_int_equal(example_main(array_length(args), args), 0);
}
int main(int argc, char* argv[]) {
UnitTest tests[] = {
unit_test(test_add),
unit_test(test_subtract),
unit_test(test_multiply),
unit_test(test_divide),
unit_test(test_divide_by_zero),
unit_test(test_find_operator_function_by_string_null_functions),
unit_test(test_find_operator_function_by_string_null_string),
unit_test(test_find_operator_function_by_string_valid_null_functions),
unit_test(test_find_operator_function_by_string_not_found),
unit_test(test_find_operator_function_by_string_found),
unit_test(test_perform_operation_null_args),
unit_test(test_perform_operation_null_operator_functions),
unit_test(test_perform_operation_null_number_of_intermediate_values),
unit_test(test_perform_operation_null_intermediate_values),
unit_test(test_perform_operation_no_arguments),
unit_test(test_perform_operation_first_arg_not_integer),
unit_test(test_perform_operation_unknown_operator),
unit_test(test_perform_operation_missing_argument),
unit_test(test_perform_operation_no_integer_after_operator),
unit_test(test_perform_operation),
unit_test(test_example_main_no_args),
unit_test(test_example_main),
};
return run_tests(tests);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include <stdio.h>
#include <database.h>
#ifdef _WIN32
#define snprintf _snprintf
#endif // _WIN32
// Connect to the database containing customer information.
DatabaseConnection* connect_to_customer_database() {
return connect_to_database("customers.abcd.org", 321);
}
/* Find the ID of a customer by his/her name returning a value > 0 if
* successful, 0 otherwise. */
unsigned int get_customer_id_by_name(
DatabaseConnection * const connection,
const char * const customer_name) {
char query_string[256];
int number_of_results;
void **results;
snprintf(query_string, sizeof(query_string),
"SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name);
number_of_results = connection->query_database(connection, query_string,
&results);
if (number_of_results != 1) {
return -1;
}
return (unsigned int)results[0];
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include <database.h>
extern DatabaseConnection* connect_to_customer_database();
extern unsigned int get_customer_id_by_name(
DatabaseConnection * const connection, const char * const customer_name);
// Mock query database function.
unsigned int mock_query_database(
DatabaseConnection* const connection, const char * const query_string,
void *** const results) {
*results = (void**)mock();
return (unsigned int)mock();
}
// Mock of the connect to database function.
DatabaseConnection* connect_to_database(const char * const database_url,
const unsigned int port) {
return (DatabaseConnection*)mock();
}
void test_connect_to_customer_database(void **state) {
will_return(connect_to_database, 0x0DA7ABA53);
assert_int_equal((int)connect_to_customer_database(), 0x0DA7ABA53);
}
/* This test fails as the mock function connect_to_database() will have no
* value to return. */
void fail_connect_to_customer_database(void **state) {
assert_true(connect_to_customer_database() ==
(DatabaseConnection*)0x0DA7ABA53);
}
void test_get_customer_id_by_name(void **state) {
DatabaseConnection connection = {
"somedatabase.somewhere.com", 12345678, mock_query_database
};
// Return a single customer ID when mock_query_database() is called.
int customer_ids = 543;
will_return(mock_query_database, &customer_ids);
will_return(mock_query_database, 1);
assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543);
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(test_connect_to_customer_database),
unit_test(test_get_customer_id_by_name),
};
return run_tests(tests);
}

37
src/example/database.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
typedef struct DatabaseConnection DatabaseConnection;
/* Function that takes an SQL query string and sets results to an array of
* pointers with the result of the query. The value returned specifies the
* number of items in the returned array of results. The returned array of
* results are statically allocated and should not be deallocated using free()
*/
typedef unsigned int (*QueryDatabase)(
DatabaseConnection* const connection, const char * const query_string,
void *** const results);
// Connection to a database.
struct DatabaseConnection {
const char *url;
unsigned int port;
QueryDatabase query_database;
};
// Connect to a database.
DatabaseConnection* connect_to_database(const char * const url,
const unsigned int port);

54
src/example/key_value.c Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
typedef struct KeyValue {
unsigned int key;
const char* value;
} KeyValue;
static KeyValue *key_values = NULL;
static unsigned int number_of_key_values = 0;
void set_key_values(KeyValue * const new_key_values,
const unsigned int new_number_of_key_values) {
key_values = new_key_values;
number_of_key_values = new_number_of_key_values;
}
// Compare two key members of KeyValue structures.
int key_value_compare_keys(const void *a, const void *b) {
return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key;
}
// Search an array of key value pairs for the item with the specified value.
KeyValue* find_item_by_value(const char * const value) {
unsigned int i;
for (i = 0; i < number_of_key_values; i++) {
if (strcmp(key_values[i].value, value) == 0) {
return &key_values[i];
}
}
return NULL;
}
// Sort an array of key value pairs by key.
void sort_items_by_key() {
qsort(key_values, number_of_key_values, sizeof(*key_values),
key_value_compare_keys);
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <string.h>
#include <cmockery.h>
/* This is duplicated here from the module setup_teardown.c to reduce the
* number of files used in this test. */
typedef struct KeyValue {
unsigned int key;
const char* value;
} KeyValue;
void set_key_values(KeyValue * const new_key_values,
const unsigned int new_number_of_key_values);
extern KeyValue* find_item_by_value(const char * const value);
extern void sort_items_by_key();
static KeyValue key_values[] = {
{ 10, "this" },
{ 52, "test" },
{ 20, "a" },
{ 13, "is" },
};
void create_key_values(void **state) {
KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values));
memcpy(items, key_values, sizeof(key_values));
*state = (void*)items;
set_key_values(items, sizeof(key_values) / sizeof(key_values[0]));
}
void destroy_key_values(void **state) {
test_free(*state);
set_key_values(NULL, 0);
}
void test_find_item_by_value(void **state) {
unsigned int i;
for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
KeyValue * const found = find_item_by_value(key_values[i].value);
assert_true(found);
assert_int_equal(found->key, key_values[i].key);
assert_string_equal(found->value, key_values[i].value);
}
}
void test_sort_items_by_key(void **state) {
unsigned int i;
KeyValue * const kv = *state;
sort_items_by_key();
for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
assert_true(kv[i - 1].key < kv[i].key);
}
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test_setup_teardown(test_find_item_by_value, create_key_values,
destroy_key_values),
unit_test_setup_teardown(test_sort_items_by_key, create_key_values,
destroy_key_values),
};
return run_tests(tests);
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <database.h>
// Connect to the database containing customer information.
DatabaseConnection* connect_to_product_database() {
return connect_to_database("products.abcd.org", 322);
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include <database.h>
extern DatabaseConnection* connect_to_product_database();
/* Mock connect to database function.
* NOTE: This mock function is very general could be shared between tests
* that use the imaginary database.h module. */
DatabaseConnection* connect_to_database(const char * const url,
const unsigned int port) {
check_expected(url);
check_expected(port);
return (DatabaseConnection*)mock();
}
void test_connect_to_product_database(void **state) {
expect_string(connect_to_database, url, "products.abcd.org");
expect_value(connect_to_database, port, 322);
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
}
/* This test will fail since the expected URL is different to the URL that is
* passed to connect_to_database() by connect_to_product_database(). */
void test_connect_to_product_database_bad_url(void **state) {
expect_string(connect_to_database, url, "products.abcd.com");
expect_value(connect_to_database, port, 322);
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
}
/* This test will fail since the mock connect_to_database() will attempt to
* retrieve a value for the parameter port which isn't specified by this
* test function. */
void test_connect_to_product_database_missing_parameter(void **state) {
expect_string(connect_to_database, url, "products.abcd.org");
will_return(connect_to_database, 0xDA7ABA53);
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(test_connect_to_product_database),
unit_test(test_connect_to_product_database_bad_url),
unit_test(test_connect_to_product_database_missing_parameter),
};
return run_tests(tests);
}

30
src/example/run_tests.c Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
// A test case that does nothing and succeeds.
void null_test_success(void **state) {
}
int main(int argc, char* argv[]) {
const UnitTest tests[] = {
unit_test(null_test_success),
};
return run_tests(tests);
}

435
src/google/cmockery.h Executable file
View File

@ -0,0 +1,435 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CMOCKERY_H_
#define CMOCKERY_H_
/*
* These headers or their equivalents should be included prior to including
* this header file.
*
* #include <stdarg.h>
* #include <stddef.h>
* #include <setjmp.h>
*
* This allows test applications to use custom definitions of C standard
* library functions and types.
*/
// For those who are used to __func__ from gcc.
#ifndef __func__
#define __func__ __FUNCTION__
#endif
// Retrieves a return value for the current function.
#define mock() _mock(__func__, __FILE__, __LINE__)
/* Stores a value to be returned by the specified function later.
* The count parameter returns the number of times the value should be returned
* by mock(). If count is set to -1 the value will always be returned.
*/
#define will_return(function, value) \
_will_return(#function, __FILE__, __LINE__, (void*)value, 1)
#define will_return_count(function, value, count) \
_will_return(#function, __FILE__, __LINE__, (void*)value, count)
/* Add a custom parameter checking function. If the event parameter is NULL
* the event structure is allocated internally by this function. If event
* parameter is provided it must be allocated on the heap and doesn't need to
* be deallocated by the caller.
*/
#define expect_check(function, parameter, check_function, check_data) \
_expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \
check_data)
/* Add an event to check a parameter, using check_expected(), against a set of
* values. See will_return() for a description of the count parameter.
*/
#define expect_in_set(function, parameter, value_array) \
expect_in_set_count(function, parameter, value_array, 1)
#define expect_in_set_count(function, parameter, value_array, count) \
_expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \
sizeof(value_array) / sizeof(value_array[0]), count)
#define expect_not_in_set(function, parameter, value_array) \
expect_not_in_set_count(function, parameter, value_array, 1)
#define expect_not_in_set_count(function, parameter, value_array, count) \
_expect_not_in_set( \
#function, #parameter, __FILE__, __LINE__, value_array, \
sizeof(value_array) / sizeof(value_array[0]), count)
/* Add an event to check a parameter, using check_expected(), against a
* signed range. Where range is minimum <= value <= maximum.
* See will_return() for a description of the count parameter.
*/
#define expect_in_range(function, parameter, minimum, maximum) \
expect_in_range_count(function, parameter, minimum, maximum, 1)
#define expect_in_range_count(function, parameter, minimum, maximum, count) \
_expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \
maximum, count)
/* Add an event to check a parameter, using check_expected(), against a
* signed range. Where range is value < minimum or value > maximum.
* See will_return() for a description of the count parameter.
*/
#define expect_not_in_range(function, parameter, minimum, maximum) \
expect_not_in_range_count(function, parameter, minimum, maximum, 1)
#define expect_not_in_range_count(function, parameter, minimum, maximum, \
count) \
_expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \
minimum, maximum, count)
/* Add an event to check whether a parameter, using check_expected(), is or
* isn't a value. See will_return() for a description of the count parameter.
*/
#define expect_value(function, parameter, value) \
expect_value_count(function, parameter, value, 1)
#define expect_value_count(function, parameter, value, count) \
_expect_value(#function, #parameter, __FILE__, __LINE__, (void*)value, \
count)
#define expect_not_value(function, parameter, value) \
expect_not_value_count(function, parameter, value, 1)
#define expect_not_value_count(function, parameter, value, count) \
_expect_not_value(#function, #parameter, __FILE__, __LINE__, \
(void*)value, count)
/* Add an event to check whether a parameter, using check_expected(),
* is or isn't a string. See will_return() for a description of the count
* parameter.
*/
#define expect_string(function, parameter, string) \
expect_string_count(function, parameter, string, 1)
#define expect_string_count(function, parameter, string, count) \
_expect_string(#function, #parameter, __FILE__, __LINE__, (void*)string, \
count)
#define expect_not_string(function, parameter, string) \
expect_not_string_count(function, parameter, string, 1)
#define expect_not_string_count(function, parameter, string, count) \
_expect_not_string(#function, #parameter, __FILE__, __LINE__, \
(void*)string, count)
/* Add an event to check whether a parameter, using check_expected() does or
* doesn't match an area of memory. See will_return() for a description of
* the count parameter.
*/
#define expect_memory(function, parameter, memory, size) \
expect_memory_count(function, parameter, memory, size, 1)
#define expect_memory_count(function, parameter, memory, size, count) \
_expect_memory(#function, #parameter, __FILE__, __LINE__, (void*)memory, \
size, count)
#define expect_not_memory(function, parameter, memory, size) \
expect_not_memory_count(function, parameter, memory, size, 1)
#define expect_not_memory_count(function, parameter, memory, size, count) \
_expect_not_memory(#function, #parameter, __FILE__, __LINE__, \
(void*)memory, size, count)
/* Add an event to allow any value for a parameter checked using
* check_expected(). See will_return() for a description of the count
* parameter.
*/
#define expect_any(function, parameter) \
expect_any_count(function, parameter, 1)
#define expect_any_count(function, parameter, count) \
_expect_any(#function, #parameter, __FILE__, __LINE__, count)
/* Determine whether a function parameter is correct. This ensures the next
* value queued by one of the expect_*() macros matches the specified variable.
*/
#define check_expected(parameter) \
_check_expected(__func__, #parameter, __FILE__, __LINE__, (void*)parameter)
// Assert that the given expression is true.
#define assert_true(c) _assert_true((int)(c), #c, __FILE__, __LINE__)
// Assert that the given expression is false.
#define assert_false(c) _assert_true(!((int)(c)), #c, __FILE__, __LINE__)
// Assert that the two given integers are equal, otherwise fail.
#define assert_int_equal(a, b) _assert_int_equal(a, b, __FILE__, __LINE__)
// Assert that the two given integers are not equal, otherwise fail.
#define assert_int_not_equal(a, b) \
_assert_int_not_equal(a, b, __FILE__, __LINE__)
// Assert that the two given strings are equal, otherwise fail.
#define assert_string_equal(a, b) \
_assert_string_equal((const char*)a, (const char*)b, __FILE__, __LINE__)
// Assert that the two given strings are not equal, otherwise fail.
#define assert_string_not_equal(a, b) \
_assert_string_not_equal((const char*)a, (const char*)b, __FILE__, \
__LINE__)
// Assert that the two given areas of memory are equal, otherwise fail.
#define assert_memory_equal(a, b, size) \
_assert_memory_equal((const char*)a, (const char*)b, size, __FILE__, \
__LINE__)
// Assert that the two given areas of memory are not equal, otherwise fail.
#define assert_memory_not_equal(a, b, size) \
_assert_memory_not_equal((const char*)a, (const char*)b, size, __FILE__, \
__LINE__)
// Assert that the specified value is >= minimum and <= maximum.
#define assert_in_range(value, minimum, maximum) \
_assert_in_range((int)value, (int)minimum, (int)maximum, __FILE__, \
__LINE__)
// Assert that the specified value is < minumum or > maximum
#define assert_not_in_range(value, minimum, maximum) \
_assert_not_in_range((int)value, (int)minimum, (int)maximum, __FILE__, \
__LINE__)
// Assert that the specified value is within a set.
#define assert_in_set(value, values, number_of_values) \
_assert_in_set(value, values, number_of_values, __FILE__, __LINE__)
// Assert that the specified value is not within a set.
#define assert_not_in_set(value, values, number_of_values) \
_assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__)
// Forces the test to fail immediately and quit.
#define fail() _fail(__FILE__, __LINE__)
// Generic method to kick off testing
#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL)
// Initializes a UnitTest structure.
#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST }
#define unit_test_setup(test, setup) \
{ #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP }
#define unit_test_teardown(test, teardown) \
{ #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN }
/* Initialize an array of UnitTest structures with a setup function for a test
* and a teardown function. Either setup or teardown can be NULL.
*/
#define unit_test_setup_teardown(test, setup, teardown) \
unit_test_setup(test, setup), \
unit_test(test), \
unit_test_teardown(test, teardown)
/*
* Run tests specified by an array of UnitTest structures. The following
* example illustrates this macro's use with the unit_test macro.
*
* void Test0();
* void Test1();
*
* int main(int argc, char* argv[]) {
* const UnitTest tests[] = {
* unit_test(Test0);
* unit_test(Test1);
* };
* return run_tests(tests);
* }
*/
#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0])
// Dynamic allocators
#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__)
#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__)
// Redirect malloc, calloc and free to the unit test allocators.
#if UNIT_TESTING
#define malloc test_malloc
#define calloc test_calloc
#define free test_free
#endif // UNIT_TESTING
/*
* Ensure mock_assert() is called. If mock_assert() is called the assert
* expression string is returned.
* For example:
*
* #define assert mock_assert
*
* void showmessage(const char *message) {
* assert(message);
* }
*
* int main(int argc, const char* argv[]) {
* expect_assert_failure(show_message(NULL));
* printf("succeeded\n");
* return 0;
* }
*/
#define expect_assert_failure(function_call) \
{ \
const char* expression = (const char*)setjmp(global_expect_assert_env); \
global_expecting_assert = 1; \
if (expression) { \
print_message("Expected assertion %s occurred\n", expression); \
global_expecting_assert = 0; \
} else { \
function_call ; \
global_expecting_assert = 0; \
print_error("Expected assert in %s\n", #function_call); \
_fail(__FILE__, __LINE__); \
} \
}
// Function prototype for setup, test and teardown functions.
typedef void (*UnitTestFunction)(void **state);
// Function that determines whether a function parameter value is correct.
typedef int (*CheckParameterValue)(const void *value, void *check_value_data);
// Type of the unit test function.
typedef enum UnitTestFunctionType {
UNIT_TEST_FUNCTION_TYPE_TEST = 0,
UNIT_TEST_FUNCTION_TYPE_SETUP,
UNIT_TEST_FUNCTION_TYPE_TEARDOWN,
} UnitTestFunctionType;
/* Stores a unit test function with its name and type.
* NOTE: Every setup function must be paired with a teardown function. It's
* possible to specify NULL function pointers.
*/
typedef struct UnitTest {
const char* name;
UnitTestFunction function;
UnitTestFunctionType function_type;
} UnitTest;
// Location within some source code.
typedef struct SourceLocation {
const char* file;
int line;
} SourceLocation;
// Event that's called to check a parameter value.
typedef struct CheckParameterEvent {
SourceLocation location;
const char *parameter_name;
CheckParameterValue check_value;
void *check_value_data;
} CheckParameterEvent;
// Used by expect_assert_failure() and mock_assert().
extern int global_expecting_assert;
extern jmp_buf global_expect_assert_env;
// Retrieves a value for the given function, as set by "will_return".
void* _mock(const char * const function, const char* const file,
const int line);
void _expect_check(
const char* const function, const char* const parameter,
const char* const file, const int line,
const CheckParameterValue check_function, void * const check_data,
CheckParameterEvent * const event, const int count);
void _expect_in_set(
const char* const function, const char* const parameter,
const char* const file, const int line, const void *values[],
const size_t number_of_values, const int count);
void _expect_not_in_set(
const char* const function, const char* const parameter,
const char* const file, const int line, const void *values[],
const size_t number_of_values, const int count);
void _expect_in_range(
const char* const function, const char* const parameter,
const char* const file, const int line,
const int minimum, const int maximum, const int count);
void _expect_not_in_range(
const char* const function, const char* const parameter,
const char* const file, const int line,
const int minimum, const int maximum, const int count);
void _expect_value(
const char* const function, const char* const parameter,
const char* const file, const int line, const void* const value,
const int count);
void _expect_not_value(
const char* const function, const char* const parameter,
const char* const file, const int line, const void* const value,
const int count);
void _expect_string(
const char* const function, const char* const parameter,
const char* const file, const int line, const char* string,
const int count);
void _expect_not_string(
const char* const function, const char* const parameter,
const char* const file, const int line, const char* string,
const int count);
void _expect_memory(
const char* const function, const char* const parameter,
const char* const file, const int line, const void* const memory,
const size_t size, const int count);
void _expect_not_memory(
const char* const function, const char* const parameter,
const char* const file, const int line, const void* const memory,
const size_t size, const int count);
void _expect_any(
const char* const function, const char* const parameter,
const char* const file, const int line, const int count);
void _check_expected(
const char * const function_name, const char * const parameter_name,
const char* file, const int line, const void* value);
// Can be used to replace assert in tested code so that in conjuction with
// check_assert() it's possible to determine whether an assert condition has
// failed without stopping a test.
void mock_assert(const int result, const char* const expression,
const char * const file, const int line);
void _will_return(const char * const function_name, const char * const file,
const int line, const void* const value, const int count);
void _assert_true(const int result, const char* const expression,
const char * const file, const int line);
void _assert_int_equal(const int a, const int b, const char * const file,
const int line);
void _assert_int_not_equal(const int a, const int b, const char * const file,
const int line);
void _assert_string_equal(const char * const a, const char * const b,
const char * const file, const int line);
void _assert_string_not_equal(const char * const a, const char * const b,
const char *file, const int line);
void _assert_memory_equal(const void * const a, const void * const b,
const size_t size, const char* const file,
const int line);
void _assert_memory_not_equal(const void * const a, const void * const b,
const size_t size, const char* const file,
const int line);
void _assert_in_range(const int value, const int minimum, const int maximum,
const char* const file, const int line);
void _assert_not_in_range(const int value, const int minimum,
const int maximum, const char* const file,
const int line);
void _assert_in_set(const void * const value, const void *values[],
const size_t number_of_values, const char* const file,
const int line);
void _assert_not_in_set(const void * const value, const void *values[],
const size_t number_of_values, const char* const file,
const int line);
void* _test_malloc(const size_t size, const char* file, const int line);
void* _test_calloc(const size_t number_of_elements, const size_t size,
const char* file, const int line);
void _test_free(void* const ptr, const char* file, const int line);
void _fail(const char * const file, const int line);
int _run_test(
const char * const function_name, const UnitTestFunction Function,
void ** const state, const UnitTestFunctionType function_type,
const void* const heap_check_point);
int _run_tests(const UnitTest * const tests, const size_t number_of_tests);
// Standard output and error print methods.
void print_message(const char* const format, ...);
void print_error(const char* const format, ...);
void vprint_message(const char* const format, va_list args);
void vprint_error(const char* const format, va_list args);
#endif // CMOCKERY_H_

139
windows/makefile Normal file
View File

@ -0,0 +1,139 @@
#
# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Microsoft Windows namke file which builds the cmockery library and example
# applications.
#
# To use this makefile...
# Select Start->Run and run "cmd.exe" to open the command line.
# Run "vsvars.bat" located in Microsoft Visual Studio's directory.
# Run "nmake" to build the cmockery library and example applications.
# Run "nmake clean" to delete all files built by this makefile.
LIBRARY_SOURCE_DIRECTORY=..\src
EXAMPLE_SOURCE_DIRECTORY=..\src\example
CFLAGS=/nologo /c /D_WIN32_WINNT=0x501 /I$(LIBRARY_SOURCE_DIRECTORY)\google \
/I$(EXAMPLE_SOURCE_DIRECTORY)
CC_COMMAND=$(CC) $(CFLAGS) $(**) /Fo$(@)
CC_COMMAND_UNIT_TEST=$(CC_COMMAND) /DUNIT_TESTING=1
LIBLINKFLAGS=/NOLOGO /MACHINE:x86 /SUBSYSTEM:console
LIBRARY_ARCHIVER=lib.exe
LIBFLAGS=$(LIBLINKFLAGS)
LIB_COMMAND=$(LIBRARY_ARCHIVER) $(LIBFLAGS) $(**) /OUT:$(@)
LINK=link.exe
LFLAGS=$(LIBLINKFLAGS) libcmt.lib kernel32.lib /NODEFAULTLIB:libc.lib
LINK_COMMAND=$(LINK) $(LFLAGS) $(**) /OUT:$(@)
.SUFFIXES: .exe .lib .obj .c
all: cmockery.lib calculator.exe calculator_test.exe allocate_module_test.exe \
assert_macro_test.exe customer_database_test.exe key_value_test.exe \
product_database_test.exe run_tests.exe
clean:
-cmd /c "@for %A in (\
cmockery.lib cmockery.obj \
calculator.exe calculator.obj \
calculator_test.exe calculator_test.obj \
calculator_test-calculator.obj \
allocate_module_test.exe allocate_module_test.obj \
allocate_module.obj \
assert_macro_test.exe assert_macro_test.obj \
assert_macro.obj \
customer_database_test.exe customer_database_test.obj \
customer_database.obj \
key_value_test.exe key_value_test.obj key_value.obj \
product_database_test.exe product_database_test.obj \
product_database.obj \
run_tests.exe run_tests.obj) do @del %A 2>NUL"
# Rules for the cmockery library.
cmockery.lib: cmockery.obj
cmockery.obj: $(LIBRARY_SOURCE_DIRECTORY)\cmockery.c
# Rules for the calculator application.
calculator.exe: calculator.obj
calculator.obj: $(EXAMPLE_SOURCE_DIRECTORY)\calculator.c
$(CC_COMMAND)
# Rules for the calculator test application.
calculator_test.exe: calculator_test.obj calculator_test-calculator.obj \
cmockery.lib
$(LINK_COMMAND)
calculator_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\calculator_test.c
calculator_test-calculator.obj: $(EXAMPLE_SOURCE_DIRECTORY)\calculator.c
$(CC_COMMAND_UNIT_TEST)
# Sample code applications.
allocate_module_test.exe: allocate_module_test.obj allocate_module.obj \
cmockery.lib
$(LINK_COMMAND)
allocate_module_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\allocate_module_test.c
allocate_module.obj: $(EXAMPLE_SOURCE_DIRECTORY)\allocate_module.c
assert_macro_test.exe: assert_macro_test.obj assert_macro.obj \
cmockery.lib
$(LINK_COMMAND)
assert_macro_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\assert_macro_test.c
assert_macro.obj: $(EXAMPLE_SOURCE_DIRECTORY)\assert_macro.c
customer_database_test.exe: customer_database_test.obj customer_database.obj \
cmockery.lib
$(LINK_COMMAND)
customer_database_test.obj: \
$(EXAMPLE_SOURCE_DIRECTORY)\customer_database_test.c
customer_database.obj: $(EXAMPLE_SOURCE_DIRECTORY)\customer_database.c
key_value_test.exe: key_value_test.obj key_value.obj \
cmockery.lib
$(LINK_COMMAND)
key_value_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\key_value_test.c
key_value.obj: $(EXAMPLE_SOURCE_DIRECTORY)\key_value.c
product_database_test.exe: product_database_test.obj product_database.obj \
cmockery.lib
$(LINK_COMMAND)
product_database_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\product_database_test.c
product_database.obj: $(EXAMPLE_SOURCE_DIRECTORY)\product_database.c
run_tests.exe: run_tests.obj cmockery.lib
$(LINK_COMMAND)
run_tests.obj: $(EXAMPLE_SOURCE_DIRECTORY)\run_tests.c
# Inference rules.
.obj.exe:
$(LINK_COMMAND)
.obj.lib:
$(LIB_COMMAND)
{$(LIBRARY_SOURCE_DIRECTORY)\}.c{}.obj:
$(CC_COMMAND)
{$(EXAMPLE_SOURCE_DIRECTORY)\}.c{}.obj:
$(CC_COMMAND_UNIT_TEST)