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:
parent
1e8d7abef1
commit
e414597c71
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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)
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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:
|
|
@ -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 <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);
|
||||
}
|
||||
</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 <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 --;
|
||||
}
|
||||
}
|
||||
|
||||
<a href="../src/example/assert_module_test.c">assert_module_test.c</a>
|
||||
-------------------------------------------------------------------------------
|
||||
#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);
|
||||
}
|
||||
</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 <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;
|
||||
}
|
||||
|
||||
<a href="../src/example/assert_macro_test.c">assert_macro_test.c</a>
|
||||
-------------------------------------------------------------------------------
|
||||
#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);
|
||||
}
|
||||
</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 <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);
|
||||
}
|
||||
|
||||
|
||||
<a href="../src/example/allocate_module_test.c">allocate_module_test.c</a>
|
||||
-------------------------------------------------------------------------------
|
||||
#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);
|
||||
}
|
||||
</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 <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <a href="#database.h"><database.h></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 <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmockery.h>
|
||||
#include <a href="#database.h"><database.h></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"><database.h></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 <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmockery.h>
|
||||
#include <a href="#database.h"><database.h></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 <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);
|
||||
}
|
||||
|
||||
<a href="../src/example/key_value_test.c">key_value_test.c</a>
|
||||
-------------------------------------------------------------------------------
|
||||
#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);
|
||||
}
|
||||
</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>
|
|
@ -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:
|
|
@ -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__)
|
||||
])
|
|
@ -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
|
||||
])
|
|
@ -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
|
|
@ -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)
|
||||
])
|
|
@ -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)
|
||||
])
|
|
@ -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])
|
|
@ -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
|
||||
])
|
|
@ -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
|
||||
])
|
|
@ -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:
|
|
@ -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:
|
|
@ -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"
|
|
@ -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'.
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
4
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -0,0 +1,7 @@
|
|||
AUTHORS
|
||||
COPYING
|
||||
ChangeLog
|
||||
INSTALL
|
||||
NEWS
|
||||
README
|
||||
doc/index.html
|
|
@ -0,0 +1,4 @@
|
|||
usr/lib
|
||||
usr/include
|
||||
usr/include/google
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
usr/lib
|
|
@ -0,0 +1,2 @@
|
|||
usr/lib/lib*.so.*
|
||||
debian/tmp/usr/lib/lib*.so.*
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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_
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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) --;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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];
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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)
|
Loading…
Reference in New Issue