[PATCH weston v2] Refactored simple unit/integration test framework and corresponding test program.

Jon A. Cruz jonc at osg.samsung.com
Mon Jun 1 09:52:13 PDT 2015


On 05/29/2015 04:24 PM, Bryce Harrington wrote:
> On Fri, May 29, 2015 at 03:33:59PM -0700, Bryce Harrington wrote:
>> On Tue, May 05, 2015 at 03:50:22PM -0700, Jon A. Cruz wrote:
>>> Refactored to a simple C-based test framework and an example program
>>> that uses it to run through some simple wayland client checks.
>>>
>>> Signed-off-by: Jon A. Cruz <jonc at osg.samsung.com>
>>
>> This is a review I started last week (took me a while since this is such
>> a huge patch), and you've since posted a v3 so don't know how relevant
>> any of this commentary still is.
> 
> I do have a couple questions, that I didn't figure out from studying
> your code:
> 
> First, is this intended to handle client-style tests?  E.g. is this
> supposed to replace the weston-tests-env bash script?  If so, how do
> weston test server instances get set up?
> 

That's going to be a follow-up addition of a new/updated test fixture or
fixtures. The test setup will list the things needed (modules, etc.) and
fire up the server in either the test setup function or the case/suite
setup function.


> Second, the current autoconf-based test suite causes test output to be
> logged in the root directory, so some test results will be there, the
> rest under logs.  Will this enable us to keep all the test output files
> together in one place?

By default this will add its log files into the current directory.
Placing them elsewhere was also going to be a follow-up change after
some discussion.

The normal way to do this would be to pass a parameter with the path of
the log file to use. However, autoconf's test runner has the limitation
that the only way to pass them is to use a script. There are a few
options including just not bothering with their system and launching
tests directly in Makefile.am, using a single test runner script with
proper param setting, a local config file, etc.

> 
> Bryce
> 
>>> ---
>>>  .gitignore                            |   3 +
>>>  Makefile.am                           |  34 +++
>>>  tools/Doxyfile                        | 318 +++++++++++++++++++++
>>>  tools/devdocs.doxyfile                | 315 +++++++++++++++++++++
>>>  tools/devtools.dox                    |  52 ++++
>>>  tools/tools.dox                       |  29 ++
>>>  tools/tools_arch_new.gv               |  60 ++++
>>>  tools/tools_arch_old.gv               |  28 ++
>>>  tools/waycheck/rough_draw.c           | 176 ++++++++++++
>>>  tools/waycheck/rough_draw.h           |  42 +++
>>>  tools/waycheck/waycheck.c             | 505 ++++++++++++++++++++++++++++++++++
>>>  tools/waycheck/waycheck.dox           |  29 ++
>>>  tools/waycheck/wtst_fixtures.c        | 289 +++++++++++++++++++
>>>  tools/waycheck/wtst_fixtures.h        | 144 ++++++++++
>>>  tools/zunitc/doc/zunitc.dox           |  67 +++++
>>>  tools/zunitc/inc/zunitc/zunitc.h      | 300 ++++++++++++++++++++
>>>  tools/zunitc/inc/zunitc/zunitc_impl.h |  76 +++++
>>>  tools/zunitc/src/zunitc_impl.c        | 496 +++++++++++++++++++++++++++++++++
>>>  tools/zunitc/test/zunitc_test.c       | 106 +++++++
>>>  19 files changed, 3069 insertions(+)
>>>  create mode 100644 tools/Doxyfile
>>>  create mode 100644 tools/devdocs.doxyfile
>>>  create mode 100644 tools/devtools.dox
>>>  create mode 100644 tools/tools.dox
>>>  create mode 100644 tools/tools_arch_new.gv
>>>  create mode 100644 tools/tools_arch_old.gv
>>>  create mode 100644 tools/waycheck/rough_draw.c
>>>  create mode 100644 tools/waycheck/rough_draw.h
>>>  create mode 100644 tools/waycheck/waycheck.c
>>>  create mode 100644 tools/waycheck/waycheck.dox
>>>  create mode 100644 tools/waycheck/wtst_fixtures.c
>>>  create mode 100644 tools/waycheck/wtst_fixtures.h
>>>  create mode 100644 tools/zunitc/doc/zunitc.dox
>>>  create mode 100644 tools/zunitc/inc/zunitc/zunitc.h
>>>  create mode 100644 tools/zunitc/inc/zunitc/zunitc_impl.h
>>>  create mode 100644 tools/zunitc/src/zunitc_impl.c
>>>  create mode 100644 tools/zunitc/test/zunitc_test.c
>>>
>>> diff --git a/.gitignore b/.gitignore
>>> index 047c386..2690bde 100644
>>> --- a/.gitignore
>>> +++ b/.gitignore
>>> @@ -98,3 +98,6 @@ weston-drm.7
>>>  weston.ini.5
>>>  
>>>  /tests/weston-ivi.ini
>>> +
>>> +waycheck
>>> +zuctest
>>> diff --git a/Makefile.am b/Makefile.am
>>> index 2f16fac..073733f 100644
>>> --- a/Makefile.am
>>> +++ b/Makefile.am
>>> @@ -1155,6 +1155,40 @@ setbacklight_CFLAGS = $(AM_CFLAGS) $(SETBACKLIGHT_CFLAGS)
>>>  setbacklight_LDADD = $(SETBACKLIGHT_LIBS)
>>>  endif
>>>  
>>> +# --------------------------------------------------------------------------
>>> +
>>> +all-local: waycheck$(EXEEXT) zuctest$(EXEEXT)
>>> +
>>> +noinst_PROGRAMS += zuctest$(EXEEXT)
>>> +
>>> +zuctest_CPPFLAGS =			\
>>> +	-I$(top_builddir)/tools/zunitc/inc
>>> +
>>> +zuctest_SOURCES = \
>>> +	tools/zunitc/src/zunitc_impl.c \
>>> +	tools/zunitc/test/zunitc_test.c
>>> +
>>> +#
>>> +
>>> +noinst_PROGRAMS += waycheck$(EXEEXT)
>>> +
>>> +waycheck_LDADD =			\
>>> +	$(WAYLAND_COMPOSITOR_LIBS)
>>> +
>>> +waycheck_CPPFLAGS =			\
>>> +	-I$(top_builddir)/tools/zunitc/inc	\
>>> +	-I$(top_builddir)/clients		\
>>> +	-I$(top_srcdir)/shared
>>> +
>>> +waycheck_SOURCES = \
>>> +	tools/zunitc/src/zunitc_impl.c \
>>> +	shared/os-compatibility.c \
>>> +	tools/waycheck/waycheck.c \
>>> +	tools/waycheck/rough_draw.c \
>>> +	tools/waycheck/wtst_fixtures.c
>>> +
>>> +# --------------------------------------------------------------------------
>>> +
>>>  EXTRA_DIST += tests/weston-tests-env
>>>  
>>>  BUILT_SOURCES +=				\
>>> diff --git a/tools/Doxyfile b/tools/Doxyfile
>>> new file mode 100644
>>> index 0000000..e42cdbb
>>> --- /dev/null
>>> +++ b/tools/Doxyfile
>>
>> Wayland puts documentation (and the doxygen config file) under
>> wayland/doc/doxygen/ .  While we don't have a doc/ subdir for weston, I
>> think for consistency we should, and this tool documentation should move
>> there.
>>
>> Wayland names the config file wayland.doxygen, so a similar file naming
>> scheme would be sensible here (or else change Wayland's file name style
>> to match, if people file this name more conventional.)
>>
>> Wayland also takes the approach of using the stock config file generated
>> by doxygen -g, IIRC, and then at run time cat it and concatenate
>> project-specific non-default parameter settings.  See the Makefile.am
>> for the doc stuff.  If possible I'd suggest following a similar approach
>> to keep things consistent.  That approach also makes it relatively easy
>> to see what non-default settings are in use.
>>
>> If you roll another patchset, you could put the stock defaults Doxygen
>> config file (and any other boilerplate-ish bits) in a separate patch, as
>> they'll not need as close of review.
>>
>>> @@ -0,0 +1,318 @@
>>> +# Doxyfile 1.8.8
>>> +
>>> +#---------------------------------------------------------------------------
>>> +# Project related configuration options
>>> +#---------------------------------------------------------------------------
>>> +DOXYFILE_ENCODING      = UTF-8
>>> +PROJECT_NAME           = "Tools"
>>> +PROJECT_NUMBER         =
>>> +PROJECT_BRIEF          =
>>> +PROJECT_LOGO           =
>>> +OUTPUT_DIRECTORY       = docs
>>> +CREATE_SUBDIRS         = NO
>>> +ALLOW_UNICODE_NAMES    = NO
>>> +OUTPUT_LANGUAGE        = English
>>> +BRIEF_MEMBER_DESC      = YES
>>> +REPEAT_BRIEF           = YES
>>> +ABBREVIATE_BRIEF       =
>>> +ALWAYS_DETAILED_SEC    = NO
>>> +INLINE_INHERITED_MEMB  = NO
>>> +FULL_PATH_NAMES        = YES
>>> +STRIP_FROM_PATH        =
>>> +STRIP_FROM_INC_PATH    =
>>> +SHORT_NAMES            = NO
>>> +JAVADOC_AUTOBRIEF      = YES
>>> +QT_AUTOBRIEF           = NO
>>> +MULTILINE_CPP_IS_BRIEF = NO
>>> +INHERIT_DOCS           = YES
>>> +SEPARATE_MEMBER_PAGES  = NO
>>> +TAB_SIZE               = 4
>>> +ALIASES                =
>>> +TCL_SUBST              =
>>> +OPTIMIZE_OUTPUT_FOR_C  = YES
>>> +OPTIMIZE_OUTPUT_JAVA   = NO
>>> +OPTIMIZE_FOR_FORTRAN   = NO
>>> +OPTIMIZE_OUTPUT_VHDL   = NO
>>> +EXTENSION_MAPPING      =
>>> +MARKDOWN_SUPPORT       = YES
>>> +AUTOLINK_SUPPORT       = YES
>>> +BUILTIN_STL_SUPPORT    = NO
>>> +CPP_CLI_SUPPORT        = NO
>>> +SIP_SUPPORT            = NO
>>> +IDL_PROPERTY_SUPPORT   = YES
>>> +DISTRIBUTE_GROUP_DOC   = NO
>>> +SUBGROUPING            = YES
>>> +INLINE_GROUPED_CLASSES = NO
>>> +INLINE_SIMPLE_STRUCTS  = NO
>>> +TYPEDEF_HIDES_STRUCT   = NO
>>> +LOOKUP_CACHE_SIZE      = 0
>>> +#---------------------------------------------------------------------------
>>> +# Build related configuration options
>>> +#---------------------------------------------------------------------------
>>> +EXTRACT_ALL            = NO
>>> +EXTRACT_PRIVATE        = NO
>>> +EXTRACT_PACKAGE        = NO
>>> +EXTRACT_STATIC         = NO
>>> +EXTRACT_LOCAL_CLASSES  = YES
>>> +EXTRACT_LOCAL_METHODS  = NO
>>> +EXTRACT_ANON_NSPACES   = NO
>>> +HIDE_UNDOC_MEMBERS     = NO
>>> +HIDE_UNDOC_CLASSES     = NO
>>> +HIDE_FRIEND_COMPOUNDS  = NO
>>> +HIDE_IN_BODY_DOCS      = NO
>>> +INTERNAL_DOCS          = NO
>>> +CASE_SENSE_NAMES       = YES
>>> +HIDE_SCOPE_NAMES       = NO
>>> +SHOW_INCLUDE_FILES     = YES
>>> +SHOW_GROUPED_MEMB_INC  = NO
>>> +FORCE_LOCAL_INCLUDES   = NO
>>> +INLINE_INFO            = YES
>>> +SORT_MEMBER_DOCS       = YES
>>> +SORT_BRIEF_DOCS        = NO
>>> +SORT_MEMBERS_CTORS_1ST = NO
>>> +SORT_GROUP_NAMES       = NO
>>> +SORT_BY_SCOPE_NAME     = NO
>>> +STRICT_PROTO_MATCHING  = NO
>>> +GENERATE_TODOLIST      = YES
>>> +GENERATE_TESTLIST      = YES
>>> +GENERATE_BUGLIST       = YES
>>> +GENERATE_DEPRECATEDLIST= YES
>>> +ENABLED_SECTIONS       =
>>> +MAX_INITIALIZER_LINES  = 30
>>> +SHOW_USED_FILES        = YES
>>> +SHOW_FILES             = YES
>>> +SHOW_NAMESPACES        = YES
>>> +FILE_VERSION_FILTER    =
>>> +LAYOUT_FILE            =
>>> +CITE_BIB_FILES         =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to warning and progress messages
>>> +#---------------------------------------------------------------------------
>>> +QUIET                  = NO
>>> +WARNINGS               = YES
>>> +WARN_IF_UNDOCUMENTED   = YES
>>> +WARN_IF_DOC_ERROR      = YES
>>> +WARN_NO_PARAMDOC       = NO
>>> +WARN_FORMAT            = "$file:$line: $text"
>>> +WARN_LOGFILE           =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the input files
>>> +#---------------------------------------------------------------------------
>>> +INPUT                  = \
>>> +		       tools.dox \
>>> +		       zunitc/doc/zunitc.dox \
>>> +		       zunitc/inc/zunitc/zunitc.h \
>>> +		       waycheck/waycheck.dox \
>>> +		       waycheck/wtst_fixtures.h \
>>> +		       waycheck/rough_draw.h
>>> +INPUT_ENCODING         = UTF-8
>>> +FILE_PATTERNS          =
>>> +RECURSIVE              = NO
>>> +EXCLUDE                =
>>> +EXCLUDE_SYMLINKS       = NO
>>> +EXCLUDE_PATTERNS       =
>>> +EXCLUDE_SYMBOLS        =
>>> +EXAMPLE_PATH           =
>>> +EXAMPLE_PATTERNS       =
>>> +EXAMPLE_RECURSIVE      = NO
>>> +IMAGE_PATH             =
>>> +INPUT_FILTER           =
>>> +FILTER_PATTERNS        =
>>> +FILTER_SOURCE_FILES    = NO
>>> +FILTER_SOURCE_PATTERNS =
>>> +USE_MDFILE_AS_MAINPAGE =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to source browsing
>>> +#---------------------------------------------------------------------------
>>> +SOURCE_BROWSER         = NO
>>> +INLINE_SOURCES         = NO
>>> +STRIP_CODE_COMMENTS    = YES
>>> +REFERENCED_BY_RELATION = NO
>>> +REFERENCES_RELATION    = NO
>>> +REFERENCES_LINK_SOURCE = YES
>>> +SOURCE_TOOLTIPS        = YES
>>> +USE_HTAGS              = NO
>>> +VERBATIM_HEADERS       = YES
>>> +CLANG_ASSISTED_PARSING = NO
>>> +CLANG_OPTIONS          =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the alphabetical class index
>>> +#---------------------------------------------------------------------------
>>> +ALPHABETICAL_INDEX     = YES
>>> +COLS_IN_ALPHA_INDEX    = 5
>>> +IGNORE_PREFIX          =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the HTML output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_HTML          = YES
>>> +HTML_OUTPUT            = html
>>> +HTML_FILE_EXTENSION    = .html
>>> +HTML_HEADER            =
>>> +HTML_FOOTER            =
>>> +HTML_STYLESHEET        =
>>> +HTML_EXTRA_STYLESHEET  =
>>> +HTML_EXTRA_FILES       =
>>> +HTML_COLORSTYLE_HUE    = 220
>>> +HTML_COLORSTYLE_SAT    = 100
>>> +HTML_COLORSTYLE_GAMMA  = 80
>>> +HTML_TIMESTAMP         = YES
>>> +HTML_DYNAMIC_SECTIONS  = NO
>>> +HTML_INDEX_NUM_ENTRIES = 100
>>> +GENERATE_DOCSET        = NO
>>> +DOCSET_FEEDNAME        = "Doxygen generated docs"
>>> +DOCSET_BUNDLE_ID       = org.doxygen.Project
>>> +DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
>>> +DOCSET_PUBLISHER_NAME  = Publisher
>>> +GENERATE_HTMLHELP      = NO
>>> +CHM_FILE               =
>>> +HHC_LOCATION           =
>>> +GENERATE_CHI           = NO
>>> +CHM_INDEX_ENCODING     =
>>> +BINARY_TOC             = NO
>>> +TOC_EXPAND             = NO
>>> +GENERATE_QHP           = NO
>>> +QCH_FILE               =
>>> +QHP_NAMESPACE          = org.doxygen.Project
>>> +QHP_VIRTUAL_FOLDER     = doc
>>> +QHP_CUST_FILTER_NAME   =
>>> +QHP_CUST_FILTER_ATTRS  =
>>> +QHP_SECT_FILTER_ATTRS  =
>>> +QHG_LOCATION           =
>>> +GENERATE_ECLIPSEHELP   = NO
>>> +ECLIPSE_DOC_ID         = org.doxygen.Project
>>> +DISABLE_INDEX          = NO
>>> +GENERATE_TREEVIEW      = NO
>>> +ENUM_VALUES_PER_LINE   = 4
>>> +TREEVIEW_WIDTH         = 250
>>> +EXT_LINKS_IN_WINDOW    = NO
>>> +FORMULA_FONTSIZE       = 10
>>> +FORMULA_TRANSPARENT    = YES
>>> +USE_MATHJAX            = NO
>>> +MATHJAX_FORMAT         = HTML-CSS
>>> +MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
>>> +MATHJAX_EXTENSIONS     =
>>> +MATHJAX_CODEFILE       =
>>> +SEARCHENGINE           = YES
>>> +SERVER_BASED_SEARCH    = NO
>>> +EXTERNAL_SEARCH        = NO
>>> +SEARCHENGINE_URL       =
>>> +SEARCHDATA_FILE        = searchdata.xml
>>> +EXTERNAL_SEARCH_ID     =
>>> +EXTRA_SEARCH_MAPPINGS  =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the LaTeX output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_LATEX         = YES
>>> +LATEX_OUTPUT           = latex
>>> +LATEX_CMD_NAME         = latex
>>> +MAKEINDEX_CMD_NAME     = makeindex
>>> +COMPACT_LATEX          = NO
>>> +PAPER_TYPE             = a4
>>> +EXTRA_PACKAGES         =
>>> +LATEX_HEADER           =
>>> +LATEX_FOOTER           =
>>> +LATEX_EXTRA_FILES      =
>>> +PDF_HYPERLINKS         = YES
>>> +USE_PDFLATEX           = YES
>>> +LATEX_BATCHMODE        = NO
>>> +LATEX_HIDE_INDICES     = NO
>>> +LATEX_SOURCE_CODE      = NO
>>> +LATEX_BIB_STYLE        = plain
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the RTF output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_RTF           = NO
>>> +RTF_OUTPUT             = rtf
>>> +COMPACT_RTF            = NO
>>> +RTF_HYPERLINKS         = NO
>>> +RTF_STYLESHEET_FILE    =
>>> +RTF_EXTENSIONS_FILE    =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the man page output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_MAN           = NO
>>> +MAN_OUTPUT             = man
>>> +MAN_EXTENSION          = .3
>>> +MAN_SUBDIR             =
>>> +MAN_LINKS              = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the XML output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_XML           = NO
>>> +XML_OUTPUT             = xml
>>> +XML_PROGRAMLISTING     = YES
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the DOCBOOK output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_DOCBOOK       = NO
>>> +DOCBOOK_OUTPUT         = docbook
>>> +DOCBOOK_PROGRAMLISTING = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options for the AutoGen Definitions output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_AUTOGEN_DEF   = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the Perl module output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_PERLMOD       = NO
>>> +PERLMOD_LATEX          = NO
>>> +PERLMOD_PRETTY         = YES
>>> +PERLMOD_MAKEVAR_PREFIX =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the preprocessor
>>> +#---------------------------------------------------------------------------
>>> +ENABLE_PREPROCESSING   = YES
>>> +MACRO_EXPANSION        = NO
>>> +EXPAND_ONLY_PREDEF     = NO
>>> +SEARCH_INCLUDES        = YES
>>> +INCLUDE_PATH           =
>>> +INCLUDE_FILE_PATTERNS  =
>>> +PREDEFINED             =
>>> +EXPAND_AS_DEFINED      =
>>> +SKIP_FUNCTION_MACROS   = YES
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to external references
>>> +#---------------------------------------------------------------------------
>>> +TAGFILES               =
>>> +GENERATE_TAGFILE       =
>>> +ALLEXTERNALS           = NO
>>> +EXTERNAL_GROUPS        = YES
>>> +EXTERNAL_PAGES         = YES
>>> +PERL_PATH              = /usr/bin/perl
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the dot tool
>>> +#---------------------------------------------------------------------------
>>> +CLASS_DIAGRAMS         = YES
>>> +MSCGEN_PATH            =
>>> +DIA_PATH               =
>>> +HIDE_UNDOC_RELATIONS   = YES
>>> +HAVE_DOT               = YES
>>> +DOT_NUM_THREADS        = 0
>>> +DOT_FONTNAME           = Helvetica
>>> +DOT_FONTSIZE           = 10
>>> +DOT_FONTPATH           =
>>> +CLASS_GRAPH            = YES
>>> +COLLABORATION_GRAPH    = YES
>>> +GROUP_GRAPHS           = YES
>>> +UML_LOOK               = NO
>>> +UML_LIMIT_NUM_FIELDS   = 10
>>> +TEMPLATE_RELATIONS     = NO
>>> +INCLUDE_GRAPH          = YES
>>> +INCLUDED_BY_GRAPH      = YES
>>> +CALL_GRAPH             = NO
>>> +CALLER_GRAPH           = NO
>>> +GRAPHICAL_HIERARCHY    = YES
>>> +DIRECTORY_GRAPH        = YES
>>> +DOT_IMAGE_FORMAT       = png
>>> +INTERACTIVE_SVG        = NO
>>> +DOT_PATH               =
>>> +DOTFILE_DIRS           =
>>> +MSCFILE_DIRS           =
>>> +DIAFILE_DIRS           =
>>> +PLANTUML_JAR_PATH      =
>>> +DOT_GRAPH_MAX_NODES    = 50
>>> +MAX_DOT_GRAPH_DEPTH    = 0
>>> +DOT_TRANSPARENT        = NO
>>> +DOT_MULTI_TARGETS      = NO
>>> +GENERATE_LEGEND        = YES
>>> +DOT_CLEANUP            = YES
>>> diff --git a/tools/devdocs.doxyfile b/tools/devdocs.doxyfile
>>> new file mode 100644
>>> index 0000000..41aa836
>>> --- /dev/null
>>> +++ b/tools/devdocs.doxyfile
>>> @@ -0,0 +1,315 @@
>>> +# Doxyfile 1.8.8
>>> +
>>> +#---------------------------------------------------------------------------
>>> +# Project related configuration options
>>> +#---------------------------------------------------------------------------
>>> +DOXYFILE_ENCODING      = UTF-8
>>> +PROJECT_NAME           = "Tool Internals"
>>> +PROJECT_NUMBER         =
>>> +PROJECT_BRIEF          =
>>> +PROJECT_LOGO           =
>>> +OUTPUT_DIRECTORY       = devdocs
>>> +CREATE_SUBDIRS         = NO
>>> +ALLOW_UNICODE_NAMES    = NO
>>> +OUTPUT_LANGUAGE        = English
>>> +BRIEF_MEMBER_DESC      = YES
>>> +REPEAT_BRIEF           = YES
>>> +ABBREVIATE_BRIEF       =
>>> +ALWAYS_DETAILED_SEC    = NO
>>> +INLINE_INHERITED_MEMB  = NO
>>> +FULL_PATH_NAMES        = YES
>>> +STRIP_FROM_PATH        =
>>> +STRIP_FROM_INC_PATH    =
>>> +SHORT_NAMES            = NO
>>> +JAVADOC_AUTOBRIEF      = YES
>>> +QT_AUTOBRIEF           = NO
>>> +MULTILINE_CPP_IS_BRIEF = NO
>>> +INHERIT_DOCS           = YES
>>> +SEPARATE_MEMBER_PAGES  = NO
>>> +TAB_SIZE               = 4
>>> +ALIASES                =
>>> +TCL_SUBST              =
>>> +OPTIMIZE_OUTPUT_FOR_C  = YES
>>> +OPTIMIZE_OUTPUT_JAVA   = NO
>>> +OPTIMIZE_FOR_FORTRAN   = NO
>>> +OPTIMIZE_OUTPUT_VHDL   = NO
>>> +EXTENSION_MAPPING      =
>>> +MARKDOWN_SUPPORT       = YES
>>> +AUTOLINK_SUPPORT       = YES
>>> +BUILTIN_STL_SUPPORT    = NO
>>> +CPP_CLI_SUPPORT        = NO
>>> +SIP_SUPPORT            = NO
>>> +IDL_PROPERTY_SUPPORT   = YES
>>> +DISTRIBUTE_GROUP_DOC   = NO
>>> +SUBGROUPING            = YES
>>> +INLINE_GROUPED_CLASSES = NO
>>> +INLINE_SIMPLE_STRUCTS  = NO
>>> +TYPEDEF_HIDES_STRUCT   = NO
>>> +LOOKUP_CACHE_SIZE      = 0
>>> +#---------------------------------------------------------------------------
>>> +# Build related configuration options
>>> +#---------------------------------------------------------------------------
>>> +EXTRACT_ALL            = YES
>>> +EXTRACT_PRIVATE        = NO
>>> +EXTRACT_PACKAGE        = NO
>>> +EXTRACT_STATIC         = NO
>>> +EXTRACT_LOCAL_CLASSES  = YES
>>> +EXTRACT_LOCAL_METHODS  = NO
>>> +EXTRACT_ANON_NSPACES   = NO
>>> +HIDE_UNDOC_MEMBERS     = NO
>>> +HIDE_UNDOC_CLASSES     = NO
>>> +HIDE_FRIEND_COMPOUNDS  = NO
>>> +HIDE_IN_BODY_DOCS      = NO
>>> +INTERNAL_DOCS          = NO
>>> +CASE_SENSE_NAMES       = YES
>>> +HIDE_SCOPE_NAMES       = NO
>>> +SHOW_INCLUDE_FILES     = YES
>>> +SHOW_GROUPED_MEMB_INC  = NO
>>> +FORCE_LOCAL_INCLUDES   = NO
>>> +INLINE_INFO            = YES
>>> +SORT_MEMBER_DOCS       = YES
>>> +SORT_BRIEF_DOCS        = NO
>>> +SORT_MEMBERS_CTORS_1ST = NO
>>> +SORT_GROUP_NAMES       = NO
>>> +SORT_BY_SCOPE_NAME     = NO
>>> +STRICT_PROTO_MATCHING  = NO
>>> +GENERATE_TODOLIST      = YES
>>> +GENERATE_TESTLIST      = YES
>>> +GENERATE_BUGLIST       = YES
>>> +GENERATE_DEPRECATEDLIST= YES
>>> +ENABLED_SECTIONS       =
>>> +MAX_INITIALIZER_LINES  = 30
>>> +SHOW_USED_FILES        = YES
>>> +SHOW_FILES             = YES
>>> +SHOW_NAMESPACES        = YES
>>> +FILE_VERSION_FILTER    =
>>> +LAYOUT_FILE            =
>>> +CITE_BIB_FILES         =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to warning and progress messages
>>> +#---------------------------------------------------------------------------
>>> +QUIET                  = NO
>>> +WARNINGS               = YES
>>> +WARN_IF_UNDOCUMENTED   = YES
>>> +WARN_IF_DOC_ERROR      = YES
>>> +WARN_NO_PARAMDOC       = NO
>>> +WARN_FORMAT            = "$file:$line: $text"
>>> +WARN_LOGFILE           =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the input files
>>> +#---------------------------------------------------------------------------
>>> +INPUT                  = \
>>> +		       devtools.dox \
>>> +		       zunitc \
>>> +		       waycheck
>>> +INPUT_ENCODING         = UTF-8
>>> +FILE_PATTERNS          =
>>> +RECURSIVE              = YES
>>> +EXCLUDE                =
>>> +EXCLUDE_SYMLINKS       = NO
>>> +EXCLUDE_PATTERNS       =
>>> +EXCLUDE_SYMBOLS        =
>>> +EXAMPLE_PATH           =
>>> +EXAMPLE_PATTERNS       =
>>> +EXAMPLE_RECURSIVE      = NO
>>> +IMAGE_PATH             =
>>> +INPUT_FILTER           =
>>> +FILTER_PATTERNS        =
>>> +FILTER_SOURCE_FILES    = NO
>>> +FILTER_SOURCE_PATTERNS =
>>> +USE_MDFILE_AS_MAINPAGE =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to source browsing
>>> +#---------------------------------------------------------------------------
>>> +SOURCE_BROWSER         = NO
>>> +INLINE_SOURCES         = NO
>>> +STRIP_CODE_COMMENTS    = YES
>>> +REFERENCED_BY_RELATION = NO
>>> +REFERENCES_RELATION    = NO
>>> +REFERENCES_LINK_SOURCE = YES
>>> +SOURCE_TOOLTIPS        = YES
>>> +USE_HTAGS              = NO
>>> +VERBATIM_HEADERS       = YES
>>> +CLANG_ASSISTED_PARSING = NO
>>> +CLANG_OPTIONS          =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the alphabetical class index
>>> +#---------------------------------------------------------------------------
>>> +ALPHABETICAL_INDEX     = YES
>>> +COLS_IN_ALPHA_INDEX    = 5
>>> +IGNORE_PREFIX          =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the HTML output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_HTML          = YES
>>> +HTML_OUTPUT            = html
>>> +HTML_FILE_EXTENSION    = .html
>>> +HTML_HEADER            =
>>> +HTML_FOOTER            =
>>> +HTML_STYLESHEET        =
>>> +HTML_EXTRA_STYLESHEET  =
>>> +HTML_EXTRA_FILES       =
>>> +HTML_COLORSTYLE_HUE    = 220
>>> +HTML_COLORSTYLE_SAT    = 100
>>> +HTML_COLORSTYLE_GAMMA  = 80
>>> +HTML_TIMESTAMP         = YES
>>> +HTML_DYNAMIC_SECTIONS  = NO
>>> +HTML_INDEX_NUM_ENTRIES = 100
>>> +GENERATE_DOCSET        = NO
>>> +DOCSET_FEEDNAME        = "Doxygen generated docs"
>>> +DOCSET_BUNDLE_ID       = org.doxygen.Project
>>> +DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
>>> +DOCSET_PUBLISHER_NAME  = Publisher
>>> +GENERATE_HTMLHELP      = NO
>>> +CHM_FILE               =
>>> +HHC_LOCATION           =
>>> +GENERATE_CHI           = NO
>>> +CHM_INDEX_ENCODING     =
>>> +BINARY_TOC             = NO
>>> +TOC_EXPAND             = NO
>>> +GENERATE_QHP           = NO
>>> +QCH_FILE               =
>>> +QHP_NAMESPACE          = org.doxygen.Project
>>> +QHP_VIRTUAL_FOLDER     = doc
>>> +QHP_CUST_FILTER_NAME   =
>>> +QHP_CUST_FILTER_ATTRS  =
>>> +QHP_SECT_FILTER_ATTRS  =
>>> +QHG_LOCATION           =
>>> +GENERATE_ECLIPSEHELP   = NO
>>> +ECLIPSE_DOC_ID         = org.doxygen.Project
>>> +DISABLE_INDEX          = NO
>>> +GENERATE_TREEVIEW      = NO
>>> +ENUM_VALUES_PER_LINE   = 4
>>> +TREEVIEW_WIDTH         = 250
>>> +EXT_LINKS_IN_WINDOW    = NO
>>> +FORMULA_FONTSIZE       = 10
>>> +FORMULA_TRANSPARENT    = YES
>>> +USE_MATHJAX            = NO
>>> +MATHJAX_FORMAT         = HTML-CSS
>>> +MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
>>> +MATHJAX_EXTENSIONS     =
>>> +MATHJAX_CODEFILE       =
>>> +SEARCHENGINE           = YES
>>> +SERVER_BASED_SEARCH    = NO
>>> +EXTERNAL_SEARCH        = NO
>>> +SEARCHENGINE_URL       =
>>> +SEARCHDATA_FILE        = searchdata.xml
>>> +EXTERNAL_SEARCH_ID     =
>>> +EXTRA_SEARCH_MAPPINGS  =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the LaTeX output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_LATEX         = YES
>>> +LATEX_OUTPUT           = latex
>>> +LATEX_CMD_NAME         = latex
>>> +MAKEINDEX_CMD_NAME     = makeindex
>>> +COMPACT_LATEX          = NO
>>> +PAPER_TYPE             = a4
>>> +EXTRA_PACKAGES         =
>>> +LATEX_HEADER           =
>>> +LATEX_FOOTER           =
>>> +LATEX_EXTRA_FILES      =
>>> +PDF_HYPERLINKS         = YES
>>> +USE_PDFLATEX           = YES
>>> +LATEX_BATCHMODE        = NO
>>> +LATEX_HIDE_INDICES     = NO
>>> +LATEX_SOURCE_CODE      = NO
>>> +LATEX_BIB_STYLE        = plain
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the RTF output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_RTF           = NO
>>> +RTF_OUTPUT             = rtf
>>> +COMPACT_RTF            = NO
>>> +RTF_HYPERLINKS         = NO
>>> +RTF_STYLESHEET_FILE    =
>>> +RTF_EXTENSIONS_FILE    =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the man page output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_MAN           = NO
>>> +MAN_OUTPUT             = man
>>> +MAN_EXTENSION          = .3
>>> +MAN_SUBDIR             =
>>> +MAN_LINKS              = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the XML output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_XML           = NO
>>> +XML_OUTPUT             = xml
>>> +XML_PROGRAMLISTING     = YES
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the DOCBOOK output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_DOCBOOK       = NO
>>> +DOCBOOK_OUTPUT         = docbook
>>> +DOCBOOK_PROGRAMLISTING = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options for the AutoGen Definitions output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_AUTOGEN_DEF   = NO
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the Perl module output
>>> +#---------------------------------------------------------------------------
>>> +GENERATE_PERLMOD       = NO
>>> +PERLMOD_LATEX          = NO
>>> +PERLMOD_PRETTY         = YES
>>> +PERLMOD_MAKEVAR_PREFIX =
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the preprocessor
>>> +#---------------------------------------------------------------------------
>>> +ENABLE_PREPROCESSING   = YES
>>> +MACRO_EXPANSION        = NO
>>> +EXPAND_ONLY_PREDEF     = NO
>>> +SEARCH_INCLUDES        = YES
>>> +INCLUDE_PATH           =
>>> +INCLUDE_FILE_PATTERNS  =
>>> +PREDEFINED             =
>>> +EXPAND_AS_DEFINED      =
>>> +SKIP_FUNCTION_MACROS   = YES
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to external references
>>> +#---------------------------------------------------------------------------
>>> +TAGFILES               =
>>> +GENERATE_TAGFILE       =
>>> +ALLEXTERNALS           = NO
>>> +EXTERNAL_GROUPS        = YES
>>> +EXTERNAL_PAGES         = YES
>>> +PERL_PATH              = /usr/bin/perl
>>> +#---------------------------------------------------------------------------
>>> +# Configuration options related to the dot tool
>>> +#---------------------------------------------------------------------------
>>> +CLASS_DIAGRAMS         = YES
>>> +MSCGEN_PATH            =
>>> +DIA_PATH               =
>>> +HIDE_UNDOC_RELATIONS   = YES
>>> +HAVE_DOT               = YES
>>> +DOT_NUM_THREADS        = 0
>>> +DOT_FONTNAME           = Helvetica
>>> +DOT_FONTSIZE           = 10
>>> +DOT_FONTPATH           =
>>> +CLASS_GRAPH            = YES
>>> +COLLABORATION_GRAPH    = YES
>>> +GROUP_GRAPHS           = YES
>>> +UML_LOOK               = NO
>>> +UML_LIMIT_NUM_FIELDS   = 10
>>> +TEMPLATE_RELATIONS     = NO
>>> +INCLUDE_GRAPH          = YES
>>> +INCLUDED_BY_GRAPH      = YES
>>> +CALL_GRAPH             = NO
>>> +CALLER_GRAPH           = NO
>>> +GRAPHICAL_HIERARCHY    = YES
>>> +DIRECTORY_GRAPH        = YES
>>> +DOT_IMAGE_FORMAT       = png
>>> +INTERACTIVE_SVG        = NO
>>> +DOT_PATH               =
>>> +DOTFILE_DIRS           = .
>>> +MSCFILE_DIRS           =
>>> +DIAFILE_DIRS           =
>>> +PLANTUML_JAR_PATH      =
>>> +DOT_GRAPH_MAX_NODES    = 50
>>> +MAX_DOT_GRAPH_DEPTH    = 0
>>> +DOT_TRANSPARENT        = NO
>>> +DOT_MULTI_TARGETS      = NO
>>> +GENERATE_LEGEND        = YES
>>> +DOT_CLEANUP            = YES
>>> diff --git a/tools/devtools.dox b/tools/devtools.dox
>>> new file mode 100644
>>> index 0000000..c1ec9fb
>>> --- /dev/null
>>> +++ b/tools/devtools.dox
>>> @@ -0,0 +1,52 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +/**
>>> + at mainpage
>>> +
>>> +- @ref zunitc - Simple test framework
>>> +
>>> +- @ref waycheck - Simple integration/acceptance test tool
>>> +
>>> + at section tools_overview Overview
>>> +
>>> +The tools area currently consists of two sub-projects (@ref zunitc and
>>> + at ref waycheck) that are refined from the prior single weston/tests source
>>> +folder.
>>> +
>>> + at subsection tools_overview_old Old Code Organization
>>> +
>>> +The original 'tests' folder contained basic weston testing with an
>>> +integrated test runner framework. Over time things progressed to the
>>> +stage where splitting apart into discrete layers was warranted.
>>> +
>>> + at dotfile tools_arch_old.gv "Original test code organization"
>>> +
>>> + at subsection tools_overview_new New Code Organization
>>> +
>>> +The test code that is not weston-specific gets split out to a separate
>>> +folder and/or folders. Then an additional testing tool 'waycheck' that is
>>> +compositor-agnostic is added.
>>> +
>>> + at dotfile tools_arch_new.gv "Refactored test code organization"
>>> +
>>> +*/
>>> diff --git a/tools/tools.dox b/tools/tools.dox
>>> new file mode 100644
>>> index 0000000..e4f5524
>>> --- /dev/null
>>> +++ b/tools/tools.dox
>>> @@ -0,0 +1,29 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +/**
>>> + at mainpage
>>> +
>>> +- @ref zunitc - Simple test framework
>>> +
>>> +- @ref waycheck - Simple integration/acceptance test tool
>>> +*/
>>> diff --git a/tools/tools_arch_new.gv b/tools/tools_arch_new.gv
>>> new file mode 100644
>>> index 0000000..fe8b6c7
>>> --- /dev/null
>>> +++ b/tools/tools_arch_new.gv
>>
>> Do these need copyright boilerplate?  (If the minimal dox files above
>> need them, figure it's worth asking...)
>>
>>> @@ -0,0 +1,60 @@
>>> +digraph toolarch_new {
>>> +    rankdir = "TB";
>>> +
>>> +    node[shape=record]
>>> +
>>> +    subgraph cluster_0 {
>>> +        label = "./tests";
>>> +
>>> +        keyboard_test_c [label = "{keyboard-test.c|tests\l}"]
>>> +        text_test_c [label = "{text-test.c|tests\l}"]
>>> +        vertex_clip_test_c [label = "{vertex-clip-test.c|tests\l}"]
>>> +
>>> +	spacer [shape = point, style = invis]
>>> +
>>> +        weston_test_client_helper [label = "{weston-test-client-helper.h/.c|Weston test protocol\l}"]
>>> +
>>> +        weston_test_c [label = "{weston-test.c|Extension protocol\nimplementation}"]
>>> +    }
>>> +
>>> +    subgraph cluster_1 {
>>> +        label = "./tools/waycheck";
>>> +
>>> +	waycheck [label = "{waycheck.c| \n \n }"]
>>> +    }
>>> +
>>> +    subgraph cluster_2 {
>>> +        label = "./tools/wayland_fixtures";
>>> +
>>> +	wtst_fixtures [label = "{wtst_fixtures.h/c|Wayland tracking structs\lWayland callbacks\l}"]
>>> +    }
>>> +
>>> +    subgraph cluster_3 {
>>> +        label = "./tools/zunitc";
>>
>> The above have assumptions of where the tool is being run from.  Make
>> sure to check this with parallel build and against distcheck.  Those
>> have flagged path issues with stuff before.
>>
>>> +	zunitc [label = "{zunitc|Test definition macros\lTest running functions\lTest reporting functions\lTest run lifecycle\l}"]
>>> +    }
>>> +
>>> +    keyboard_test_c -> weston_test_client_helper
>>> +    keyboard_test_c -> wtst_fixtures
>>> +    keyboard_test_c -> zunitc
>>> +    vertex_clip_test_c -> zunitc
>>> +    text_test_c -> weston_test_client_helper
>>> +    text_test_c -> wtst_fixtures
>>> +    text_test_c -> zunitc
>>> +
>>> +    waycheck -> wtst_fixtures
>>> +    waycheck -> zunitc
>>> +
>>> +    wtst_fixtures -> zunitc
>>> +
>>> +    edge [style = dashed, arrowhead = open]
>>> +    weston_test_client_helper -> weston_test_c
>>> +
>>> +    edge [style = invis]
>>> +    weston_test_client_helper -> zunitc
>>> +
>>> +    text_test_c -> spacer
>>> +    keyboard_test_c -> spacer
>>> +    spacer -> weston_test_client_helper
>>> +}
>>> diff --git a/tools/tools_arch_old.gv b/tools/tools_arch_old.gv
>>> new file mode 100644
>>> index 0000000..b746121
>>> --- /dev/null
>>> +++ b/tools/tools_arch_old.gv
>>> @@ -0,0 +1,28 @@
>>> +digraph toolarch_old {
>>> +    rankdir = "TB";
>>> +
>>> +    node[shape = record]
>>> +
>>> +    subgraph cluster_0 {
>>> +        label = "./tests";
>>> +
>>> +        keyboard_test_c [label = "{keyboard-test.c|tests\l}"]
>>> +        text_test_c [label = "{text-test.c|tests\l}"]
>>> +        vertex_clip_test_c [label = "{vertex-clip-test.c|tests\l}"]
>>> +
>>> +        weston_test_client_helper [label = "{weston-test-client-helper.h/.c|Wayland tracking structs\lWeston test protocol\lWayland callbacks\lTest run lifecycle\l}"]
>>> +
>>> +        weston_test_c [label = "{weston-test.c|Extension protocol\nimplementation}"]
>>> +        weston_test_runner [label = "{weston-test-runner.h/.c|Test definition macros\lTest running functions\lTest reporting functions\lTest run lifecycle\l}"]
>>> +    }
>>> +
>>> +    weston_test_client_helper -> weston_test_runner
>>> +    keyboard_test_c -> weston_test_client_helper
>>> +    keyboard_test_c -> weston_test_runner
>>> +    vertex_clip_test_c -> weston_test_runner
>>> +    text_test_c -> weston_test_client_helper
>>> +    text_test_c -> weston_test_runner
>>> +
>>> +    edge [style = dashed, arrowhead = open]
>>> +    weston_test_client_helper -> weston_test_c
>>> +}
>>> diff --git a/tools/waycheck/rough_draw.c b/tools/waycheck/rough_draw.c
>>> new file mode 100644
>>> index 0000000..9506d68
>>> --- /dev/null
>>> +++ b/tools/waycheck/rough_draw.c
>>> @@ -0,0 +1,176 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>
>> include config.h?
>>
>>> +#include <stddef.h>
>>> +
>>> +#include "rough_draw.h"
>>> +
>>> +static void fillRect(pixel *raw, pixel val, int width, int height, int stride)
>>
>> Wayland/Weston code style puts the return type on a separate line ahead
>> of the function name.
>>
>>> +{
>>> +	int x = 0;
>>> +	int y = 0;
>>> +
>>> +	for (y = 0; y < height; ++y) {
>>> +		pixel *ptr = raw + (y * stride);
>>> +		for (x = 0; x < width; ++x) {
>>> +			*(ptr++) = val;
>>> +		}
>>> +	}
>>> +}
>>
>> memset?
>>
>>> +static pixel meld(pixel val1, pixel val2, double factor)
>>> +{
>>> +	pixel result = val1;
>>> +	unsigned char *p0 = (unsigned char *)&result;
>>> +	unsigned char *p1 = (unsigned char *)&val2;
>>> +	size_t i;
>>> +	for (i = 0; i < sizeof(pixel); ++i) {
>>> +		p0[i] = ((int)(((p0[i] << 8) * (1.0 - factor))
>>> +			 + ((p1[i] << 8) * factor))) >> 8;
>>> +	}
>>> +	return result;
>>> +}
>>> +
>>> +static void gradRect(pixel *raw, pixel val1, pixel val2,
>>> +		     int width, int height, int stride)
>>
>> Wayland style is not to use camel case.
>>
>>> +{
>>> +	int x = 0;
>>> +	int y = 0;
>>> +
>>> +	double dwidth = (double)width;
>>> +	for (x = 0; x < width; ++x) {
>>
>> nitpick, but I'd put a linebreak before the for, and none before the
>> dwidth decl.
>>
>>> +		pixel melded = meld(val1, val2, x / dwidth);
>>> +		for (y = 0; y < height; ++y) {
>>> +			pixel *ptr = raw + (y * stride) + x;
>>> +			*ptr = melded;
>>> +		}
>>> +	}
>>> +}
>>> +
>>> +void draw_bars(pixel *raw, int width, int height)
>>
>> doxygen comments for this function would be nice.
>>
>>> +{
>>> +	pixel bars[] = {0xffb4b4b4, 0xffb4b410, 0xff10b4b4, 0xff10b410,
>>> +			0xffb410b4, 0xffb41010, 0xff1010b4};
>>> +	if (raw) {
>>> +		int y0 = ((height * 1.75) / 3);
>>> +		int y1 = ((height * 2) / 3);
>>> +		int y2 = ((height * 3) / 4);
>>> +		int h1 = y1 - y0;
>>> +		int h2 = height - y2;
>>> +		int w1 = width / 8;
>>> +		int w2 = (width * 0.75) / 7;
>>> +		int xr = (width * 7) / 8;
>>> +
>>> +		fillRect(raw, 0x7f1f1f1f, width, height, width);
>>> +
>>> +		// left gray:
>>
>> No C++ comments.  (I know... but I got dinged for using them.)
>>
>> I notice you use these throughout the patchset; they'll all need changed
>> to C style comments.
>>
>>> +		fillRect(raw, 0xff686868, w1, y0, width);
>>> +		fillRect(raw + (y0 * width), 0xff10ebeb, w1, h1, width);
>>> +		fillRect(raw + (y1 * width), 0xffebeb10, w1, h1, width);
>>> +		fillRect(raw + (y2 * width), 0xff313131, w1, h2, width);
>>> +
>>> +		// right gray:
>>> +		fillRect(raw + xr, 0xff686868, w1, y0, width);
>>> +		fillRect(raw + xr + (y0 * width), 0xff1010eb, w1, h1, width);
>>> +		fillRect(raw + xr + (y1 * width), 0xffeb1010, w1, h1, width);
>>> +		fillRect(raw + xr + (y2 * width), 0xff313131, w1, h2, width);
>>> +
>>> +		int xoff = w1;
>>
>> I believe Wayland likes type definitions to be up at top.  If we're
>> allowing it to be mid-function, then some of the rest of this patch
>> would benefit from it (e.g. the iter vars of for loops).
>>
>>> +		fillRect(raw + xoff + (y0 * width), 0xffebebeb, w2, h1, width);
>>> +		fillRect(raw + xoff + (y1 * width), 0xff101010, w2, h1, width);
>>> +
>>> +		double barSpan = (width * 0.75);
>>> +		size_t barCount = sizeof(bars) / sizeof(bars[0]);
>>> +		size_t i = 0;
>>> +		for (i = 0; i < barCount; ++i)
>>
>> i is set to 0 twice here.
>>
>>> +		{
>>> +			xoff = (barSpan * i) / barCount;
>>> +			int ww = (barSpan * (i + 1)) / barCount;
>>> +			ww -= xoff;
>>> +			xoff += w1;
>>> +			fillRect(raw + xoff, bars[i], ww, y0, width);
>>> +		}
>>> +
>>> +		int hw = width - (w1 + w1 + w2);
>>> +		// Gray horiz:
>>> +		xoff = w1 + w2;
>>> +		fillRect(raw + xoff + (y0 * width), 0xffb4b4b4, hw, h1, width);
>>> +		gradRect(raw + xoff + (y1 * width), 0xff101010, 0xffebebeb,
>>> +			 hw, h1, width);
>>> +
>>
>> Sorry for another useless nitpick, but I typically prefer to use
>> #defines for the colors, so I can group the definitions in one place if
>> I want to tweak the color palette later.
>>
>>> +
>>> +		xoff = (width * 0.85625) / 3;
>>> +		int w3 = (width * 0.64375) / 3;
>>> +		fillRect(raw + w1 + (y2 * width), 0xff101010, width - (w1 * 2),
>>> +			 h2, width);
>>> +		fillRect(raw + xoff + (y2 * width), 0xffebebeb, w3, h2, width);
>>> +
>>> +		int w4 = (width * 0.10625) / 3;
>>> +		xoff = (width * 1.765625) / 3;
>>> +		fillRect(raw + xoff + (y2 * width), 0xff0c0c0c, w4, h2, width);
>>> +
>>> +		xoff = (width * 1.98125) / 3;
>>> +		fillRect(raw + xoff + (y2 * width), 0xff141414, w4, h2, width);
>>> +
>>> +		xoff = (width * 2.196875) / 3;
>>> +		fillRect(raw + xoff + (y2 * width), 0xff191919, w4, h2, width);
>>> +	}
>>> +}
>>> +
>>> +void draw_crosshairs(pixel *raw, int width, int height)
>>> +{
>>> +	if (raw) {
>>> +		pixel fg = 0x7f000000;
>>> +		pixel bg = 0x7f7f7f7f;
>>> +		int x = (width + 1) / 2;
>>> +		int y = (height + 1) / 2;
>>> +
>>> +		fillRect(raw + ((y - 1) * width), bg,
>>> +			 width, 3, width);
>>> +		fillRect(raw + (y * width), fg, width, 1, width);
>>> +
>>> +		fillRect(raw + ((y - 2) * width), bg,
>>> +			 width / 3, 5, width);
>>> +		fillRect(raw + ((y - 1) * width), fg,
>>> +			 width / 3, 3, width);
>>> +		fillRect(raw + ((y - 2) * width + (width * 2 / 3)), bg,
>>> +			 width / 3, 5, width);
>>> +		fillRect(raw + ((y - 1) * width + (width * 2 / 3)), fg,
>>> +			 width / 3, 3, width);
>>> +
>>> +//
>>> +
>>> +		fillRect(raw + x - 1, bg,
>>> +			 3, height, width);
>>> +		fillRect(raw + x, fg,
>>> +			 1, height, width);
>>> +
>>> +		fillRect(raw + x - 2, bg,
>>> +			 5, height / 3, width);
>>> +		fillRect(raw + x - 1, fg,
>>> +			 3, height / 3, width);
>>> +		fillRect(raw + x - 2 + ((height * 2 / 3) * width), bg,
>>> +			 5, height / 3, width);
>>> +		fillRect(raw + x - 1 + ((height * 2 / 3) * width), fg,
>>> +			 3, height / 3, width);
>>> +	}
>>> +}
>>> diff --git a/tools/waycheck/rough_draw.h b/tools/waycheck/rough_draw.h
>>> new file mode 100644
>>> index 0000000..e8317aa
>>> --- /dev/null
>>> +++ b/tools/waycheck/rough_draw.h
>>> @@ -0,0 +1,42 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +#ifndef ROUGH_DRAW_H_SEEN_
>>> +#define ROUGH_DRAW_H_SEEN_
>>> +
>>> +#ifdef __cplusplus
>>> +extern "C" {
>>> +#endif
>>> +
>>> +#include <stdint.h>
>>> +
>>> +typedef uint32_t pixel;
>>> +
>>> +void draw_bars(pixel *raw, int width, int height);
>>> +
>>> +void draw_crosshairs(pixel *raw, int width, int height);
>>> +
>>> +#ifdef __cplusplus
>>> +} // extern "C"
>>> +#endif
>>> +
>>> +#endif // ROUGH_DRAW_H_SEEN_
>>> diff --git a/tools/waycheck/waycheck.c b/tools/waycheck/waycheck.c
>>> new file mode 100644
>>> index 0000000..b990dde
>>> --- /dev/null
>>> +++ b/tools/waycheck/waycheck.c
>>> @@ -0,0 +1,505 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +#include "config.h"
>>> +
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <string.h>
>>> +#include <unistd.h>
>>> +#include <stdbool.h>
>>> +
>>> +#include <sys/types.h>
>>> +#include <sys/stat.h>
>>> +#include <fcntl.h>
>>> +
>>> +#include <sys/mman.h>
>>> +
>>> +#include <linux/input.h>
>>> +#include <wayland-client.h>
>>> +
>>> +
>>> +#include "os-compatibility.h"
>>> +#include "rough_draw.h"
>>> +#include "wtst_fixtures.h"
>>> +#include "zunitc/zunitc.h"
>>> +
>>> +// - - - - - - - - - -
>>> +
>>> +/**
>>> + * Baseline test to see if a connection can be made to the Wayland server.
>>> + */
>>> +ZUC_TEST(BaseTest, CanConnectDisplay)
>>> +{
>>> +	struct wl_display *display = wl_display_connect(NULL);
>>> +
>>> +	ZUC_EXPECT_TRUE(display != NULL);
>>> +
>>> +	if (display) {
>>> +		wl_display_disconnect(display);
>>> +		display = NULL;
>>> +	}
>>> +}
>>
>> Are these just example tests to go with the harness, or do they actually
>> need to get run?  If the latter, maybe they should move to tests/?
>>
>>> +// A very simple case that only exercises the test fixture.
>>> +ZUC_TEST(BaseTest, HelloWayland)
>>> +{
>>> +	wtst_ctx *ctx = wtst_ctx_create();
>>> +
>>> +	ZUC_EXPECT_TRUE(ctx != NULL);
>>> +
>>> +	wtst_ctx_destroy(ctx);
>>> +}
>>> +
>>> +ZUC_TEST(BaseTest, AdvertisesRequired)
>>> +{
>>> +	char const *required[] = {
>>> +		"wl_compositor",
>>> +		"wl_data_device_manager",
>>> +		//wl_drm
>>> +		//wl_input_method
>>> +		//wl_input_panel
>>> +		"wl_output",
>>> +		//wl_scaler
>>> +		"wl_seat",
>>> +		"wl_shell",
>>> +		"wl_shm",
>>> +		"wl_subcompositor",
>>> +		//wl_text_input_manager
>>> +	};
>>> +
>>> +	wtst_ctx *ctx = wtst_ctx_create();
>>> +
>>> +	int num_required = sizeof(required) / sizeof(required[0]);
>>
>> I think there's an ARRAY_SIZE() macro to do this.
>>
>>> +	int i;
>>> +	for (i = 0; i < num_required; i++) {
>>> +		printf("Check %s\n", required[i]);
>>> +		ZUC_EXPECT_TRUE(wtst_is_global_advertised(ctx, required[i]));
>>> +	}
>>> +
>>> +	wtst_ctx_destroy(ctx);
>>> +}
>>> +
>>> +
>>> +// Forward declaration of internal testing structs:
>>> +typedef struct _wtst_shm_pool wtst_shm_pool;
>>> +typedef struct _wtst_pointer wtst_pointer;
>>> +typedef struct _wtst_shell_surface wtst_shell_surface;
>>> +typedef struct _wtst_surface wtst_surface;
>>> +
>>> +typedef void (*button_cb)(uint32_t serial, uint32_t time,
>>> +			  uint32_t button, uint32_t state);
>>> +
>>> +// Simple testing helpers:
>>> +static pixel *wtst_shm_pool_get_membuf(wtst_shm_pool *pool);
>>> +static struct wl_shm_pool *wtst_shm_pool_get_pool(wtst_shm_pool *pool);
>>> +static void wtst_shm_pool_consume(wtst_shm_pool *pool, size_t mem_used);
>>> +static struct wl_surface *wtst_shell_surface_get_surface(wtst_shell_surface *);
>>> +
>>> +static wtst_shm_pool *wtst_create_mempool(struct wl_shm *shm,
>>> +					  int fd, size_t flen);
>>> +
>>> +static wtst_shell_surface *wtst_create_shell_surface(struct wl_compositor *
>>> +						     compositor,
>>> +						     struct wl_shell *shell);
>>> +
>>> +static wtst_pointer *set_pointer_with_cursor(wtst_shm_pool *pool,
>>> +					     unsigned int width,
>>> +					     unsigned int height,
>>> +					     int32_t hit_x, int32_t hit_y,
>>> +					     struct wl_compositor *compositor,
>>> +					     struct wl_pointer *pointer);
>>> +
>>> +static void set_button_cb(wtst_shell_surface *shell_surface,
>>> +			  button_cb callback);
>>> +
>>> +//
>>> +
>>> +static const struct wl_pointer_listener pointer_listener;
>>> +
>>> +static bool keep_alive = true;
>>> +
>>> +static void handle_button(uint32_t serial, uint32_t time,
>>> +			  uint32_t button, uint32_t state)
>>> +{
>>> +	keep_alive = false;
>>> +}
>>> +
>>> +static const uint32_t PIXEL_FORMAT = WL_SHM_FORMAT_ARGB8888;
>>> +
>>> +
>>> +ZUC_TEST(BaseTest, DoTheWork)
>>
>> 'DoTheWork' seems not very descriptive...  CommunicateWithServer would
>> be more descriptive but maybe there's something better.
>>
>>> +{
>>> +	wtst_ctx *ctx = wtst_ctx_create();
>>> +
>>> +	keep_alive = false; // Don't run the main loop for normal testing
>>> +
>>> +	// 320x200 == 4:3
>>> +
>>> +	// 320x180
>>> +	// 355x200~
>>> +	// 480x270
>>> +	// 640x360
>>> +	const int surf_width = 355;
>>> +	const int surf_height = 200;
>>> +
>>> +	const int cursor_size = 45;
>>> +
>>> +	size_t needed = sizeof(pixel) * surf_width * surf_height;
>>> +	needed += sizeof(pixel) * cursor_size * cursor_size;
>>> +
>>> +	int anon = os_create_anonymous_file(needed);
>>> +	wtst_shm_pool *pool = wtst_create_mempool(ctx->shm, anon, needed);
>>> +	struct wl_buffer *buffer = NULL;
>>> +	if (pool) {
>>> +		pixel *mem = wtst_shm_pool_get_membuf(pool);
>>> +		draw_bars(mem, surf_width, surf_height);
>>> +
>>> +		struct wl_shm_pool *shpool =
>>> +			wtst_shm_pool_get_pool(pool);
>>> +		buffer = wl_shm_pool_create_buffer(shpool,
>>> +						 0,
>>> +						 surf_width,
>>> +						 surf_height,
>>> +						 surf_width * sizeof(pixel),
>>> +						 PIXEL_FORMAT);
>>> +		wtst_shm_pool_consume(pool,
>>> +				      surf_width * surf_height * sizeof(pixel));
>>> +	}
>>> +
>>> +	wtst_shell_surface *sh_surface =
>>> +		wtst_create_shell_surface(ctx->compositor, ctx->shell);
>>> +
>>> +	if (buffer) {
>>> +		struct wl_surface *surface =
>>> +			wtst_shell_surface_get_surface(sh_surface);
>>> +
>>> +		wl_surface_attach(surface, buffer, 0, 0);
>>> +		wl_surface_commit(surface);
>>> +	}
>>> +
>>> +	int mid_hit = cursor_size / 2;
>>> +	wtst_pointer *pointer = set_pointer_with_cursor(pool,
>>> +							cursor_size,
>>> +							cursor_size,
>>> +							mid_hit, mid_hit,
>>> +							ctx->compositor,
>>> +							ctx->pointer);
>>
>> Check pointer?
>>
>>> +
>>> +	set_button_cb(sh_surface, handle_button);
>>> +	wl_pointer_add_listener(ctx->pointer, &pointer_listener, pointer);
>>> +
>>> +	while (keep_alive) {
>>> +		if (wl_display_dispatch(ctx->display) < 0)
>>> +			keep_alive = false;
>>> +	}
>>> +
>>> +	//hello_free_buffer(buffer);
>>> +	wl_buffer_destroy(buffer);
>>> +	//hello_cleanup_wayland();
>>
>> stray bits?
>>
>>> +	wtst_ctx_destroy(ctx);
>>> +}
>>> +
>>> +int main( int argc, const char* argv[] )
>>> +{
>>> +	ZUC_ADD_TEST(BaseTest, CanConnectDisplay);
>>> +	ZUC_ADD_TEST(BaseTest, HelloWayland);
>>> +	ZUC_ADD_TEST(BaseTest, AdvertisesRequired);
>>> +	ZUC_ADD_TEST(BaseTest, DoTheWork);
>>> +
>>> +	ZUC_RUN_TESTS();
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +// ========================================================================
>>> +// ========================================================================
>>> +// ========================================================================
>>> +// ========================================================================
>>> +
>>> +struct _wtst_shm_pool {
>>> +	struct wl_shm_pool *pool;
>>> +	//
>>> +	int fd;
>>> +	pixel *membuf;
>>> +	size_t flen;
>>> +	size_t used;
>>> +};
>>> +
>>> +struct _wtst_pointer {
>>> +	struct wl_pointer *pointer;
>>> +	//
>>> +	pixel *membuf;
>>> +	struct wl_buffer *buffer;
>>> +	struct wl_surface *surface; /**< Surface containing the image. */
>>> +	struct wl_surface *current_surface;
>>> +	int32_t hit_x;
>>> +	int32_t hit_y;
>>> +};
>>> +
>>> +struct _wtst_shell_surface {
>>> +	struct wl_shell_surface *shell_surface;
>>> +	//
>>> +	struct wl_surface *surface; /**< surface that this is wrapping. */
>>> +	struct wl_shell_surface_listener listener;
>>> +};
>>> +
>>> +struct _wtst_surface {
>>> +	struct wl_surface *surface;
>>> +	//
>>> +	button_cb button;
>>> +};
>>> +
>>> +pixel *wtst_shm_pool_get_membuf(wtst_shm_pool *pool)
>>> +{
>>> +	return (pool) ? pool->membuf : NULL;
>>> +}
>>> +
>>> +struct wl_shm_pool *wtst_shm_pool_get_pool(wtst_shm_pool *pool)
>>> +{
>>> +	return (pool) ? pool->pool : NULL;
>>> +}
>>> +
>>> +static void wtst_shm_pool_consume(wtst_shm_pool *pool, size_t mem_used)
>>> +{
>>> +	if (pool)
>>> +		pool->used += mem_used;
>>> +}
>>> +
>>> +wtst_shm_pool *wtst_create_mempool(struct wl_shm *shm, int fd, size_t flen)
>>> +{
>>> +	wtst_shm_pool *wtst_pool = malloc(sizeof(wtst_shm_pool));
>>> +	if (wtst_pool) {
>>
>> Maybe just return early here if it's null?
>>
>> 	if (wtst_pool == NULL)
>> 		return NULL;
>>
>>> +		memset(wtst_pool, 0, sizeof(*wtst_pool));
>>
>> Since you're malloc'ing and memset'ing this to 0, it would be better to
>> just use calloc instead of malloc.  That should simplify this logic, and
>> in some circumstances calloc can run faster.
>>
>>> +		wtst_pool->fd = fd;
>>> +		wtst_pool->flen = flen;
>>> +		wtst_pool->membuf = mmap(NULL, flen, PROT_READ | PROT_WRITE,
>>> +					 MAP_SHARED, fd, 0);
>>> +		if (wtst_pool->membuf == MAP_FAILED) {
>>> +			perror("ERROR: unable to memmap");
>>
>> s/memmap/mmap/
>>
>> Also, may as well free wtst_pool and return NULL at this point; all the
>> following logic will be short circuited anyway.
>>
>>> +		} else {
>>> +			wtst_pool->pool = wl_shm_create_pool(shm, fd, flen);
>>> +			if (!wtst_pool->pool) {
>>> +				perror("ERROR: Unable to create pool");
>>> +				munmap(wtst_pool->membuf, flen);
>>> +			}
>>> +		}
>>> +
>>> +		if (!wtst_pool->pool) {
>>> +			free(wtst_pool);
>>> +			wtst_pool = NULL;
>>> +		}
>>> +	}
>>> +
>>> +	return wtst_pool;
>>> +}
>>> +
>>> +static void shell_surface_ping(void *data,
>>> +			       struct wl_shell_surface *shell_surface,
>>> +			       uint32_t serial)
>>> +{
>>> +    wl_shell_surface_pong(shell_surface, serial);
>>> +}
>>> +
>>> +static void shell_surface_configure(void *data,
>>> +    struct wl_shell_surface *shell_surface,
>>> +    uint32_t edges, int32_t width, int32_t height)
>>> +{
>>> +}
>>> +
>>> +static const struct wl_shell_surface_listener
>>> +shell_surface_listener = {
>>> +	.ping = shell_surface_ping,
>>> +	.configure = shell_surface_configure,
>>> +};
>>> +
>>> +wtst_shell_surface *wtst_create_shell_surface(struct wl_compositor *compositor,
>>> +					      struct wl_shell *shell)
>>> +{
>>> +	wtst_shell_surface *wss = malloc(sizeof(wtst_shell_surface));
>>
>> Looks like if wss is NULL, none of the following logic is carried out,
>> so why not just check it and return NULL directly here.  That would
>> simplify the conditionals.
>>
>>> +	if (wss) {
>>> +		memset(wss, 0, sizeof(*wss));
>>> +		wss->listener.ping = shell_surface_ping;
>>> +		wss->listener.configure = shell_surface_configure;
>>> +
>>> +		wss->surface = wl_compositor_create_surface(compositor);
>>> +	}
>>> +
>>> +	if (wss && wss->surface) {
>>> +		wss->shell_surface = wl_shell_get_shell_surface(shell,
>>> +								wss->surface);
>>> +		if (wss->shell_surface) {
>>> +			wl_shell_surface_add_listener(wss->shell_surface,
>>> +						      &wss->listener,
>>> +						      wss);
>>> +			wl_shell_surface_set_toplevel(wss->shell_surface);
>>> +			wl_shell_surface_set_user_data(wss->shell_surface, wss);
>>> +			wl_surface_set_user_data(wss->surface, NULL);
>>> +		}
>>> +	}
>>> +
>>> +	if (wss && (!wss->surface || !wss->shell_surface)) {
>>> +		if (wss->surface)
>>> +			wl_surface_destroy(wss->surface);
>>> +		free(wss);
>>> +		wss = NULL;
>>> +	}
>>> +
>>> +	return wss;
>>> +}
>>
>> There's a common C idiom (not sure what the proper name of it is; it's
>> fills the role of a destructor), which uses a goto statement to jump to
>> cleanup code.  E.g.
>>
>> if (wss->surface == NULL)
>> 	goto error;
>>
>> /* ... */
>> return wss;
>>
>> error:
>> 	if (wss->surface)
>> 		wl_surface_destroy(wss->surface);
>> 	free(wss);
>> 	return NULL;
>>
>>> +struct wl_surface *
>>> +wtst_shell_surface_get_surface(wtst_shell_surface *sh_surface)
>>> +{
>>> +	return (sh_surface) ? sh_surface->surface : NULL;
>>> +}
>>> +
>>> +
>>> +void set_button_cb(wtst_shell_surface *shell_surface, button_cb callback)
>>> +{
>>> +	if (shell_surface && shell_surface->surface) {
>>> +		wtst_surface *wsurf =
>>> +			wl_surface_get_user_data(shell_surface->surface);
>>> +		if (!wsurf) {
>>> +			wsurf = malloc(sizeof(wtst_surface));
>>> +			if (wsurf) {
>>> +				memset(wsurf, 0, sizeof(*wsurf));
>>> +				wsurf->surface = shell_surface->surface;
>>> +				wl_surface_set_user_data(wsurf->surface,
>>> +							 wsurf);
>>> +			}
>>> +		}
>>> +
>>> +		if (wsurf)
>>> +			wsurf->button = callback;
>>> +	}
>>> +}
>>> +
>>> +wtst_pointer *set_pointer_with_cursor(wtst_shm_pool *pool,
>>> +				      unsigned int width, unsigned int height,
>>> +				      int32_t hit_x, int32_t hit_y,
>>> +				      struct wl_compositor *compositor,
>>> +				      struct wl_pointer *pointer)
>>> +{
>>> +	wtst_pointer *wtptr = malloc(sizeof(wtst_pointer));
>>> +	if (wtptr) {
>>> +		memset(wtptr, 0, sizeof(*wtptr));
>>
>> Use calloc
>>
>>> +		wtptr->pointer = pointer;
>>> +		wtptr->hit_x = hit_x;
>>> +		wtptr->hit_y = hit_y;
>>> +
>>> +		wtptr->surface = wl_compositor_create_surface(compositor);
>>> +		if (wtptr->surface) {
>>> +			int32_t stride = width * sizeof(pixel);
>>> +
>>> +			wtptr->membuf = pool->membuf;
>>> +			wtptr->membuf += pool->used / sizeof(*wtptr->membuf);
>>> +			draw_crosshairs(wtptr->membuf, width, height);
>>> +			//wtptr->membuf[0] = 0xfffc0000;
>>> +
>>> +			wtptr->buffer = wl_shm_pool_create_buffer(pool->pool,
>>> +								  pool->used,
>>> +								  width,
>>> +								  height,
>>> +								  stride,
>>> +								  PIXEL_FORMAT);
>>> +			pool->used += width * height * sizeof(pixel);
>>> +		}
>>> +	}
>>> +
>>> +	if (wtptr && wtptr->buffer) {
>>> +		draw_crosshairs(wtptr->membuf, width, height);
>>> +		//wtptr->membuf[0] = 0xffc00000;
>>> +	}
>>> +
>>> +	if (wtptr && !wtptr->buffer) {
>>> +		if (wtptr->surface)
>>> +			wl_surface_destroy(wtptr->surface);
>>> +		free(wtptr);
>>> +		wtptr = NULL;
>>> +	}
>>> +
>>> +	wl_pointer_set_user_data(pointer, wtptr);
>>> +
>>> +	return wtptr;
>>> +}
>>> +
>>> +
>>> +static void foo_enter(void *data,
>>> +		      struct wl_pointer *wl_pointer,
>>> +		      uint32_t serial, struct wl_surface *surface,
>>> +		      wl_fixed_t surface_x, wl_fixed_t surface_y)
>>> +{
>>> +	wtst_pointer *pointer = (wtst_pointer *)data;
>>> +	if (pointer) {
>>> +		pointer->current_surface = surface;
>>> +
>>> +		wl_surface_attach(pointer->surface, pointer->buffer, 0, 0);
>>> +		wl_surface_commit(pointer->surface);
>>> +		wl_pointer_set_cursor(pointer->pointer, serial,
>>> +				      pointer->surface,
>>> +				      pointer->hit_x, pointer->hit_y);
>>> +	}
>>> +}
>>> +
>>> +static void foo_leave(void *data,
>>> +		      struct wl_pointer *wl_pointer, uint32_t serial,
>>> +		      struct wl_surface *wl_surface)
>>> +{
>>> +	wtst_pointer *pointer = (wtst_pointer *)data;
>>> +	if (pointer)
>>> +		pointer->current_surface = NULL;
>>> +}
>>> +
>>> +static void foo_motion(void *data,
>>> +			   struct wl_pointer *wl_pointer, uint32_t time,
>>> +			   wl_fixed_t surface_x, wl_fixed_t surface_y)
>>> +{
>>> +}
>>> +
>>> +static void foo_button(void *data,
>>> +			   struct wl_pointer *wl_pointer, uint32_t serial,
>>> +			   uint32_t time, uint32_t button, uint32_t state)
>>> +{
>>> +	wtst_pointer *pointer = (wtst_pointer *)data;
>>> +	if (pointer && pointer->current_surface) {
>>> +		wtst_surface *wsurf =
>>> +			wl_surface_get_user_data(pointer->current_surface);
>>> +		if (wsurf && wsurf->button)
>>> +			wsurf->button(serial, time, button, state);
>>> +	}
>>> +}
>>> +
>>> +static void foo_axis(void *data,
>>> +			 struct wl_pointer *wl_pointer, uint32_t time,
>>> +			 uint32_t axis, wl_fixed_t value)
>>> +{
>>> +}
>>> +
>>> +static const struct wl_pointer_listener pointer_listener = {
>>> +	.enter = foo_enter,
>>> +	.leave = foo_leave,
>>> +	.motion = foo_motion,
>>> +	.button = foo_button,
>>> +	.axis = foo_axis
>>> +};
>>
>> s/foo/example_test/g
>>
>>> diff --git a/tools/waycheck/waycheck.dox b/tools/waycheck/waycheck.dox
>>> new file mode 100644
>>> index 0000000..66ae65b
>>> --- /dev/null
>>> +++ b/tools/waycheck/waycheck.dox
>>> @@ -0,0 +1,29 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +/**
>>> + at page waycheck
>>> +
>>> +A simple integration/acceptance tool to exercise Wayland compositors.
>>> +
>>> +Tests use @ref zunitc for their infrastructure, and most include use of a common wtst_ctx test fixture.
>>> +*/
>>> \ No newline at end of file
>>> diff --git a/tools/waycheck/wtst_fixtures.c b/tools/waycheck/wtst_fixtures.c
>>> new file mode 100644
>>> index 0000000..832818b
>>> --- /dev/null
>>> +++ b/tools/waycheck/wtst_fixtures.c
>>> @@ -0,0 +1,289 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>
>> include config.h
>>
>>> +#include "wtst_fixtures.h"
>>> +
>>> +#include <stdint.h>
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <string.h>
>>> +
>>> +#include <wayland-client.h>
>>> +
>>> +typedef struct wtst_advertised {
>>> +	uint32_t name;
>>> +	char *interface;
>>> +	uint32_t version;
>>> +	//
>>> +	struct wtst_advertised *next;
>>> +} wtst_advertised;
>>> +
>>> +struct wtst_ctx_private {
>>> +	int val;
>>> +	wtst_advertised *adverts;
>>> +};
>>> +
>>> +static void reg_global(void *data,
>>> +		       struct wl_registry *registry,
>>> +		       uint32_t name,
>>> +		       const char *interface,
>>> +		       uint32_t version);
>>> +
>>> +static void reg_global_remove(void *data,
>>> +			      struct wl_registry *registry,
>>> +			      uint32_t name);
>>> +
>>> +static void add_global_advert(wtst_ctx *ctx,
>>> +			      uint32_t name,
>>> +			      const char *interface,
>>> +			      uint32_t version);
>>> +
>>> +static wtst_ctx_private *wtst_ctx_private_create(void);
>>> +
>>> +static void wtst_ctx_private_destroy(wtst_ctx_private *private);
>>> +
>>> +static int logle = 0;
>>
>> log_level ?
>>
>>> +
>>> +wtst_ctx *wtst_ctx_create(void)
>>> +{
>>> +	wtst_ctx *ctx = malloc(sizeof(*ctx));
>>> +	if (!ctx) {
>>> +		perror("Unable to allocate context.");
>>
>> return NULL here, and avoid the indent for the else clause
>>
>>> +	} else {
>>> +		memset(ctx, 0, sizeof(*ctx));
>>
>> calloc
>>
>>> +		ctx->reg_listener = malloc(sizeof(*(ctx->reg_listener)));
>>> +		memset(ctx->reg_listener, 0, sizeof(*(ctx->reg_listener)));
>>
>> calloc
>>
>>> +		ctx->display = wl_display_connect(NULL);
>>> +		if (!ctx->display) {
>>> +			perror("Unable to connect to display");
>>> +			free(ctx);
>>> +			ctx = NULL;
>>
>> return NULL here, and avoid the indent for the else clause
>>
>>> +		} else {
>>> +			ctx->private = wtst_ctx_private_create();
>>> +
>>> +			ctx->registry = wl_display_get_registry(ctx->display);
>>> +
>>> +			ctx->reg_listener->global = reg_global;
>>> +			ctx->reg_listener->global_remove = reg_global_remove;
>>> +
>>> +			wl_registry_add_listener(ctx->registry,
>>> +						 ctx->reg_listener,
>>> +						 ctx);
>>> +			wl_display_sync(ctx->display);
>>> +			wl_display_roundtrip(ctx->display);
>>> +		}
>>> +	}
>>> +
>>> +	return ctx;
>>> +}
>>> +
>>> +void wtst_ctx_destroy(wtst_ctx *ctx)
>>> +{
>>> +	if (ctx) {
>>
>> Just do:
>>
>> if (!ctx)
>> 	return;
>>
>>> +		if (ctx->registry)
>>> +			wl_registry_destroy(ctx->registry);
>>> +		if (ctx->reg_listener)
>>> +			free(ctx->reg_listener);
>>> +//
>>> +
>>> +		if (ctx->compositor)
>>> +			wl_compositor_destroy(ctx->compositor);
>>> +		if (ctx->display)
>>> +			wl_display_disconnect(ctx->display);
>>> +		if (ctx->shm)
>>> +			wl_shm_destroy(ctx->shm);
>>> +		if (ctx->shell)
>>> +			wl_shell_destroy(ctx->shell);
>>> +		if (ctx->seat)
>>> +			wl_seat_destroy(ctx->seat);
>>> +		if (ctx->pointer)
>>> +			wl_pointer_destroy(ctx->pointer);
>>> +
>>> +		wtst_ctx_private_destroy(ctx->private);
>>> +
>>> +		free(ctx);
>>> +	}
>>> +}
>>> +
>>> +wtst_ctx_private *wtst_ctx_private_create(void)
>>> +{
>>> +	wtst_ctx_private *private = malloc(sizeof(wtst_ctx_private));
>>> +	if (private) {
>>> +		memset(private, 0, sizeof(*private));
>>
>> calloc
>>
>>> +		// fill in simple marker
>>> +		private->val = 0x59;
>>> +	}
>>> +
>>> +	return private;
>>> +}
>>> +
>>> +void wtst_ctx_private_destroy(wtst_ctx_private *private)
>>> +{
>>> +	if (private) {
>>> +		if (private->adverts) {
>>> +			// TODO
>>> +		}
>>> +		free(private);
>>> +	}
>>> +}
>>> +
>>> +
>>> +void reg_global(void *data,
>>> +		struct wl_registry *registry,
>>> +		uint32_t name,
>>> +		const char *interface,
>>> +		uint32_t version)
>>> +{
>>> +	struct wtst_ctx *ctx = (struct wtst_ctx *)data;
>>> +	if (logle > 1) {
>>> +		printf("reg_global ++: %2d   %s  v%d\n",
>>> +		       name, interface, version);
>>> +	}
>>> +
>>> +	add_global_advert(ctx, name, interface, version);
>>> +
>>> +	if (strcmp(interface, wl_seat_interface.name) == 0) {
>>> +		if (ctx->seat)
>>> +			wl_seat_destroy(ctx->seat);
>>> +		ctx->seat = wl_registry_bind(registry,
>>> +					    name,
>>> +					    &wl_seat_interface,
>>> +					    version);
>>> +		ctx->seat_name = name;
>>> +
>>> +		ctx->pointer = wl_seat_get_pointer(ctx->seat);
>>> +
>>> +	} else if (strcmp(interface, wl_compositor_interface.name) == 0) {
>>> +		if (ctx->compositor)
>>> +			wl_compositor_destroy(ctx->compositor);
>>> +		ctx->compositor = wl_registry_bind(registry,
>>> +						   name,
>>> +						   &wl_compositor_interface,
>>> +						   version);
>>> +		ctx->compositor_name = name;
>>> +	} else if (strcmp(interface, wl_shm_interface.name) == 0) {
>>> +		if (ctx->shm)
>>> +			wl_shm_destroy(ctx->shm);
>>> +		ctx->shm = wl_registry_bind(registry,
>>> +					    name,
>>> +					    &wl_shm_interface,
>>> +					    version);
>>> +		ctx->shm_name = name;
>>> +	} else if (strcmp(interface, wl_shell_interface.name) == 0) {
>>> +		if (ctx->shell)
>>> +			wl_shell_destroy(ctx->shell);
>>> +		ctx->shell = wl_registry_bind(registry,
>>> +					      name,
>>> +					      &wl_shell_interface,
>>> +					      version);
>>> +		ctx->shell_name = name;
>>> +	}
>>> +}
>>> +
>>> +void reg_global_remove(void *data,
>>> +		       struct wl_registry *registry,
>>> +		       uint32_t name)
>>> +{
>>> +	struct wtst_ctx *ctx = (struct wtst_ctx *)data;
>>> +	if (logle > 1)
>>> +		printf("reg_global --: %2d\n", name);
>>> +	// TODO remove item from ctx list
>>> +	if (name == ctx->seat_name) {
>>> +		if (ctx->seat)
>>> +			wl_seat_destroy(ctx->seat);
>>> +		ctx->seat = NULL;
>>> +		ctx->seat_name = 0;
>>> +
>>> +		wl_pointer_destroy(ctx->pointer);
>>> +		ctx->pointer = 0;
>>> +	} else if (name == ctx->compositor_name) {
>>> +		if (ctx->compositor)
>>> +			wl_compositor_destroy(ctx->compositor);
>>> +		ctx->compositor = NULL;
>>> +		ctx->compositor_name = 0;
>>> +	} else if (name == ctx->shm_name) {
>>> +		if (ctx->shm)
>>> +			wl_shm_destroy(ctx->shm);
>>> +		ctx->shm = NULL;
>>> +		ctx->shm_name = 0;
>>> +	} else if (name == ctx->shell_name) {
>>> +		if (ctx->shell)
>>> +			wl_shell_destroy(ctx->shell);
>>> +		ctx->shell = NULL;
>>> +		ctx->shell_name = 0;
>>> +	}
>>> +}
>>> +
>>> +// --
>>> +
>>> +void add_global_advert(wtst_ctx *ctx,
>>> +		       uint32_t name,
>>> +		       const char *interface,
>>> +		       uint32_t version)
>>> +{
>>> +	if (ctx && ctx->private) {
>>> +		// See if we've got this interface already
>>> +		wtst_advertised *curr;
>>> +		for (curr = ctx->private->adverts; curr; curr = curr->next) {
>>> +			if (strcmp(curr->interface, interface) == 0)
>>> +				break;
>>> +		}
>>> +
>>> +		if (curr) {
>>> +			// Update these in case they have changed.
>>> +			curr->name = name;
>>> +			curr->version = version;
>>> +		} else {
>>> +			// create a new one
>>> +			wtst_advertised *advert =
>>> +				malloc(sizeof(wtst_advertised));
>>> +			memset(advert, 0, sizeof(*advert));
>>
>> calloc
>>
>>> +			advert->name = name;
>>> +			advert->interface = strdup(interface);
>>> +			advert->version = version;
>>> +			curr = ctx->private->adverts;
>>> +			while (curr && curr->next) {
>>> +				curr = curr->next;
>>> +			}
>>> +			if (curr)
>>> +				curr->next = advert;
>>> +			else
>>> +				ctx->private->adverts = advert;
>>> +		}
>>> +	}
>>> +}
>>> +
>>> +int wtst_is_global_advertised(wtst_ctx *ctx, char const *interface)
>>> +{
>>> +	int found = 0;
>>> +	if (ctx && ctx->private && interface) {
>>> +		wtst_advertised *curr = ctx->private->adverts;
>>> +		while (curr && strcmp(interface, curr->interface)) {
>>> +			curr = curr->next;
>>> +		}
>>> +		found = curr != NULL;
>>> +	}
>>> +	return found;
>>> +}
>>> diff --git a/tools/waycheck/wtst_fixtures.h b/tools/waycheck/wtst_fixtures.h
>>> new file mode 100644
>>> index 0000000..bfffb9d
>>> --- /dev/null
>>> +++ b/tools/waycheck/wtst_fixtures.h
>>> @@ -0,0 +1,144 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +#ifndef WTST_FIXTURES_H
>>> +#define WTST_FIXTURES_H
>>> +
>>> +#ifdef __cplusplus
>>> +extern "C" {
>>> +#endif
>>> +
>>> +/**
>>> + * @file
>>> + * Common helpers for Wayland tests.
>>> + */
>>> +
>>> +#include <stdint.h>
>>> +
>>> +/**
>>> + * Mapping of the public fixture struct.
>>> + */
>>> +typedef struct wtst_ctx wtst_ctx;
>>> +
>>> +/**
>>> + * Mapping of the private fixture struct.
>>> + */
>>> +typedef struct wtst_ctx_private wtst_ctx_private;
>>> +
>>> +//
>>> +
>>> +/**
>>> + * Test fixture that holds the basics for simple Wayland client testing.
>>> + *
>>> + * @see wtst_ctx_create()
>>> + * @see wtst_ctx_destroy()
>>> + */
>>> +struct wtst_ctx
>>> +{
>>> +	/** The display the client is connected to. */
>>> +	struct wl_display *display;
>>> +
>>> +	//
>>> +	/** The registry the client is connected to. */
>>> +	struct wl_registry *registry;
>>> +
>>> +	//
>>> +
>>> +	/** Main compositor as advertised and updated by the registry. */
>>> +	struct wl_compositor *compositor;
>>> +
>>> +	/** Current main compositor name advertised by the registry. */
>>> +	uint32_t compositor_name;
>>> +
>>> +	/**
>>> +	 * Main shared memory object as advertised and updated by the
>>> +	 * registry.
>>> +	 */
>>> +	struct wl_shm *shm;
>>> +
>>> +	/** Current shared memory object name advertised by the registry. */
>>> +	uint32_t shm_name;
>>> +
>>> +	/** Main shell as advertised and updated by the registry. */
>>> +	struct wl_shell *shell;
>>> +
>>> +	/** Current shell name advertised by the registry. */
>>> +	uint32_t shell_name;
>>> +
>>> +	/** Main seat as advertised and updated by the registry. */
>>> +	struct wl_seat *seat;
>>> +
>>> +	/** Current seat name advertised by the registry. */
>>> +	uint32_t seat_name;
>>> +
>>> +	//
>>> +
>>> +	/** Pointer from the current seat. @see seat */
>>> +	struct wl_pointer *pointer;
>>> +
>>> +	//
>>> +
>>> +	/** Listener registered with the registry. */
>>> +	struct wl_registry_listener *reg_listener;
>>> +
>>> +	//
>>
>> There are empty C++ comments like the above scattered around; is that
>> just stray leftovers, or are they intended as organizational separators?
>> In either case, they need removed or changed.
>>
>>> +	/** Context for internal implementation details. */
>>> +	wtst_ctx_private *private;
>>> +};
>>> +
>>> +//
>>> +
>>> +/**
>>> + * Creates an instance of the test fixture.
>>> + *
>>> + * @return a pointer to a test fixture upon success, NULL otherwise.
>>> + * @see wtst_ctx_destroy()
>>> + */
>>> +wtst_ctx *wtst_ctx_create(void);
>>> +
>>> +/**
>>> + * Destroys a test fixture.
>>> + *
>>> + * @param ctx pointer to a test fixture to destroy.
>>> + * It should have previously been created via wtst_ctx_create().
>>> + * @see wtst_ctx_create()
>>> + */
>>> +void wtst_ctx_destroy(wtst_ctx *ctx);
>>> +
>>> +/**
>>> + * Determines of an interface has been advertized by the Wayland registry
>>> + * as being present.
>>> + *
>>> + * @param ctx the test fixture in use.
>>> + * @param interface the name of the interface to query.
>>> + * @return true if the interface is supported, false otherwise.
>>> + */
>>> +int wtst_is_global_advertised(wtst_ctx *ctx, char const *interface);
>>> +
>>> +//
>>> +
>>> +#ifdef __cplusplus
>>> +} // extern "C"
>>> +#endif
>>> +
>>> +#endif // WTST_FIXTURES_H
>>> diff --git a/tools/zunitc/doc/zunitc.dox b/tools/zunitc/doc/zunitc.dox
>>> new file mode 100644
>>> index 0000000..dab03b6
>>> --- /dev/null
>>> +++ b/tools/zunitc/doc/zunitc.dox
>>> @@ -0,0 +1,67 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +/**
>>> + at page zunitc zunitc
>>> +
>>> +A simple test framework in plain C suitable for basic unit and integration testing.
>>> +
>>> +The main rationale for creating this framework was to have a simple to use testing
>>> +framework with tests implemented in C using common patterns and under a
>>> +compatible license. The structure of the test code and macro use is intended to
>>> +follow common patterns established by frameworks such as Boost Test and Google Test.
>>> +
>>> +
>>> +To get started, one or more tests should be defined via ZUC_TEST(), which sets up
>>> +automatic test registration via gcc extensions. To actually execute tests,
>>> +ZUC_RUN_TESTS() should be called.
>>> +
>>> +
>>> +Tests can use several ZUC_EXPECT_* or ZUC_ASSERT_* checks to validate
>>> +conditions. The ZUC_EXPECT_* ones upon failure will mark the current test
>>> +as failing, but allow execution to continue. On the other hand, the
>>> +ZUC_ASSERT_* tests will mark the current test as failed and then immediately
>>> +terminate the test.
>>
>> That'll be a handy feature.
>>
>>> +The set of non-fatal test checks are
>>> +
>>> +- ZUC_EXPECT_TRUE()
>>> +- ZUC_EXPECT_FALSE()
>>> +- ZUC_EXPECT_EQ()
>>> +- ZUC_EXPECT_NE()
>>> +- ZUC_EXPECT_LT()
>>> +- ZUC_EXPECT_LE()
>>> +- ZUC_EXPECT_GT()
>>> +- ZUC_EXPECT_GE()
>>> +
>>> +The set of fatal test checks are
>>> +
>>> +- ZUC_ASSERT_TRUE()
>>> +- ZUC_ASSERT_FALSE()
>>> +- ZUC_ASSERT_EQ()
>>> +- ZUC_ASSERT_NE()
>>> +- ZUC_ASSERT_LT()
>>> +- ZUC_ASSERT_LE()
>>> +- ZUC_ASSERT_GT()
>>> +- ZUC_ASSERT_GE()
>>
>> Since there are tests for explicit values true and false, would it make
>> sense to have one for specific value NULL?
>>
>>> +*/
>>> diff --git a/tools/zunitc/inc/zunitc/zunitc.h b/tools/zunitc/inc/zunitc/zunitc.h
>>> new file mode 100644
>>> index 0000000..9d033cd
>>> --- /dev/null
>>> +++ b/tools/zunitc/inc/zunitc/zunitc.h
>>> @@ -0,0 +1,300 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +#ifndef Z_UNIT_C_H_SEEN_
>>> +#define Z_UNIT_C_H_SEEN_
>>> +
>>> +#ifdef __cplusplus
>>> +extern "C" {
>>> +#endif
>>> +
>>> +/**
>>> + * @file
>>> + * Simple unit test framework declarations.
>>> + */
>>> +
>>> +#include "zunitc/zunitc_impl.h"
>>> +
>>> +/**
>>> + * Adds a test to the list of those to be run.
>>> + * @param tcase the name for the test case to group this test under.
>>> + * @param test the name of this specific test.
>>> + */
>>> +#define ZUC_ADD_TEST(tcase, test) \
>>> +	zucimpl_add_test(zuctest_##tcase##_##test, #tcase, #test)
>>> +
>>> +/**
>>> + * Runs all tests that have been registered.
>>> + */
>>> +#define ZUC_RUN_TESTS() \
>>> +	zucimpl_run_tests()
>>> +
>>> +/**
>>> + * Defines a test case that can be registered to run.
>>> + */
>>> +#define ZUC_TEST(tcase, test) \
>>> +	static void zuctest_##tcase##_##test(void)
>>> +
>>> +//#define ZUC_TEST_F(tcase, test) static void zuctest_##tcase##_##test(void)
>>
>> stray?
>>
>>> +
>>> +/**
>>> + * Verfies that the specified expression is true and marks the test as failed
>>> + * if it is not.
>>> + *
>>> + * @param condition the expression that is expected to be true.
>>> + * @note it is far better to use a more specific check when possible
>>> + * (e.g. ZUC_EXPECT_EQ(), ZUC_EXPECT_NE(), etc.)
>>> + */
>>> +#define ZUC_EXPECT_TRUE(condition) \
>>> +	zucimpl_expect_true(condition, __FILE__, __LINE__, #condition)
>>> +
>>> +/**
>>> + * Verfies that the specified expression is false and marks the test as failed
>>> + * if it is not.
>>> + *
>>> + * @param condition the expression that is expected to be false.
>>> + * @note it is far better to use a more specific check when possible
>>> + * (e.g. ZUC_EXPECT_EQ(), ZUC_EXPECT_NE(), etc.)
>>> + */
>>> +#define ZUC_EXPECT_FALSE(condition) \
>>> +	zucimpl_expect_false(condition, __FILE__, __LINE__, #condition)
>>> +
>>> +/**
>>> + * Verfies that the values of the specified expressions match and marks
>>> + * the test as failed if they do not.
>>> + *
>>> + * @param expected the value the result should hold.
>>> + * @param actual the actual value seen in testing.
>>> + */
>>> +#define ZUC_EXPECT_EQ(expected, actual) \
>>> +	zucimpl_expect_eq((expected), (actual), __FILE__, __LINE__, #actual)
>>> +
>>> +/**
>>> + * Verfies that the values of the specified expressions differ and marks
>>> + * the test as failed if they do not.
>>> + *
>>> + * @param expected the value the result should not hold.
>>> + * @param actual the actual value seen in testing.
>>> + */
>>> +#define ZUC_EXPECT_NE(expected, actual) \
>>> +	zucimpl_expect_ne((expected), (actual), __FILE__, __LINE__, #actual)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is less than the value
>>> + * of the second expression and marks the test as failed if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be lesser than the other.
>>> + * @param rhs the expression whose value should be greater than the other.
>>> + */
>>> +#define ZUC_EXPECT_LT(lhs, rhs) \
>>> +	zucimpl_expect_lt((lhs), (rhs), __FILE__, __LINE__, #lhs, #rhs)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is less than or equal
>>> + * to the value of the second expression and marks the test as failed if
>>> + * it is not.
>>> + *
>>> + * @param lhs the expression whose value should be lesser than or equal to
>>> + * the other.
>>> + * @param rhs the expression whose value should be greater than or equal to
>>> + * the other.
>>> + */
>>> +#define ZUC_EXPECT_LE(lhs, rhs) \
>>> +	zucimpl_expect_le((lhs), (rhs), __FILE__, __LINE__, #lhs, #rhs)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is greater than the
>>> + * value of the second expression and marks the test as failed if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be greater than the other.
>>> + * @param rhs the expression whose value should be lesser than the other.
>>> + */
>>> +#define ZUC_EXPECT_GT(lhs, rhs) \
>>> +	zucimpl_expect_gt((lhs), (rhs), __FILE__, __LINE__, #lhs, #rhs)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is greater than or equal
>>> + * to the value of the second expression and marks the test as failed if
>>> + * it is not.
>>> + *
>>> + * @param lhs the expression whose value should be greater than or equal to
>>> + * the other.
>>> + * @param rhs the expression whose value should be lesser than or equal to
>>> + * the other.
>>> + */
>>> +#define ZUC_EXPECT_GE(lhs, rhs) \
>>> +	zucimpl_expect_ge((lhs), (rhs), __FILE__, __LINE__, #lhs, #rhs)
>>> +
>>> +
>>> +
>>> +/**
>>> + * Verfies that the specified expression is true, marks the test as failed
>>> + * and terminates the test if it is not.
>>> + *
>>> + * @param condition the expression that is expected to be true.
>>> + * @note it is far better to use a more specific check when possible
>>> + * (e.g. ZUC_EXPECT_EQ(), ZUC_EXPECT_NE(), etc.)
>>> + */
>>> +#define ZUC_ASSERT_TRUE(condition) \
>>> +	do { \
>>> +		if (zucimpl_expect_true(condition, \
>>> +					__FILE__, __LINE__, \
>>> +					#condition)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verfies that the specified expression is false, marks the test as
>>> + * failed and terminates the test if it is not.
>>> + *
>>> + * @param condition the expression that is expected to be false.
>>> + * @note it is far better to use a more specific check when possible
>>> + * (e.g. ZUC_EXPECT_EQ(), ZUC_EXPECT_NE(), etc.)
>>> + */
>>> +#define ZUC_ASSERT_FALSE(condition) \
>>> +	do { \
>>> +		if (zucimpl_expect_false(condition, \
>>> +					 __FILE__, __LINE__, \
>>> +					 #condition)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verfies that the values of the specified expressions match, marks the
>>> + * test as failed and terminates the test if they do not.
>>> + *
>>> + * @param expected the value the result should hold.
>>> + * @param actual the actual value seen in testing.
>>> + */
>>> +#define ZUC_ASSERT_EQ(expected, actual) \
>>> +	do { \
>>> +		if (zucimpl_expect_eq((expected), (actual), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #actual)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verfies that the values of the specified expressions differ, marks the
>>> + * test as failed and terminates the test if they do not.
>>> + *
>>> + * @param expected the value the result should not hold.
>>> + * @param actual the actual value seen in testing.
>>> + */
>>> +#define ZUC_ASSERT_NE(expected, actual) \
>>> +	do { \
>>> +		if (zucimpl_expect_ne((expected), (actual), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #actual)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is less than the value
>>> + * of the second expression, marks the test as failed and terminates the
>>> + * test if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be lesser than the other.
>>> + * @param rhs the expression whose value should be greater than the other.
>>> + */
>>> +#define ZUC_ASSERT_LT(lhs, rhs) \
>>> +	do { \
>>> +		if (zucimpl_expect_lt((lhs), (rhs), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #lhs, #rhs)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is less than or equal
>>> + * to the value of the second expression, marks the test as failed and
>>> + * terminates the test if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be lesser than or equal to
>>> + * the other.
>>> + * @param rhs the expression whose value should be greater than or equal to
>>> + * the other.
>>> + */
>>> +#define ZUC_ASSERT_LE(lhs, rhs) \
>>> +	do { \
>>> +		if (zucimpl_expect_le((lhs), (rhs), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #lhs, #rhs)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is greater than the
>>> + * value of the second expression, marks the test as failed and terminates
>>> + * the test if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be greater than the other.
>>> + * @param rhs the expression whose value should be lesser than the other.
>>> + */
>>> +#define ZUC_ASSERT_GT(lhs, rhs) \
>>> +	do { \
>>> +		if (zucimpl_expect_gt((lhs), (rhs), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #lhs, #rhs)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +/**
>>> + * Verifies that the value of the first expression is greater than or equal
>>> + * to the value of the second expression, marks the test as failed and
>>> + * terminates the test if it is not.
>>> + *
>>> + * @param lhs the expression whose value should be greater than or equal to
>>> + * the other.
>>> + * @param rhs the expression whose value should be lesser than or equal to
>>> + * the other.
>>> + */
>>> +#define ZUC_ASSERT_GE(lhs, rhs) \
>>> +	do { \
>>> +		if (zucimpl_expect_ge((lhs), (rhs), \
>>> +				      __FILE__, __LINE__, \
>>> +				      #lhs, #rhs)) { \
>>> +			return; \
>>> +		} \
>>> +	} \
>>> +	while (0)
>>> +
>>> +#ifdef __cplusplus
>>> +} // extern "C"
>>> +#endif
>>> +
>>> +#endif // Z_UNIT_C_H_SEEN_
>>> diff --git a/tools/zunitc/inc/zunitc/zunitc_impl.h b/tools/zunitc/inc/zunitc/zunitc_impl.h
>>> new file mode 100644
>>> index 0000000..8e95f24
>>> --- /dev/null
>>> +++ b/tools/zunitc/inc/zunitc/zunitc_impl.h
>>> @@ -0,0 +1,76 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +#ifndef Z_UNIT_C_IMPL_H_SEEN_
>>> +#define Z_UNIT_C_IMPL_H_SEEN_
>>> +
>>> +#ifdef __cplusplus
>>> +extern "C" {
>>> +#endif
>>> +
>>> +typedef void (*zucimpl_test_fn)(void);
>>> +
>>> +void zucimpl_add_test(zucimpl_test_fn testFn,
>>> +		      char const *caseName, char const *testName);
>>> +
>>> +void zucimpl_run_tests(void);
>>> +
>>> +int zucimpl_testFailed(void);
>>> +
>>> +int zucimpl_expect_true(int condition,
>>> +			char const *file, int line,
>>> +			const char *valueStr);
>>> +
>>> +int zucimpl_expect_false(int condition,
>>> +			 char const *file, int line,
>>> +			 const char *valueStr);
>>> +
>>> +int zucimpl_expect_eq(int expected, int actual,
>>> +		      char const *file, int line,
>>> +		      const char *valueStr);
>>> +
>>> +int zucimpl_expect_ne(int expected, int actual,
>>> +		      char const *file, int line,
>>> +		      const char *valueStr);
>>> +
>>> +int zucimpl_expect_lt(int lhs, int rhs,
>>> +		      char const *file, int line,
>>> +		      const char *lhsStr, const char* rhsStr);
>>> +
>>> +int zucimpl_expect_le(int lhs, int rhs,
>>> +		      char const *file, int line,
>>> +		      const char *lhsStr, const char* rhsStr);
>>> +
>>> +int zucimpl_expect_gt(int lhs, int rhs,
>>> +		      char const *file, int line,
>>> +		      const char *lhsStr, const char* rhsStr);
>>> +
>>> +int zucimpl_expect_ge(int lhs, int rhs,
>>> +		      char const *file, int line,
>>> +		      const char *lhsStr, const char* rhsStr);
>>> +
>>> +
>>> +#ifdef __cplusplus
>>> +}
>>> +#endif
>>> +
>>> +#endif // Z_UNIT_C_IMPL_H_SEEN_
>>> diff --git a/tools/zunitc/src/zunitc_impl.c b/tools/zunitc/src/zunitc_impl.c
>>> new file mode 100644
>>> index 0000000..2b4c8ea
>>> --- /dev/null
>>> +++ b/tools/zunitc/src/zunitc_impl.c
>>> @@ -0,0 +1,496 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>
>> include config.h
>>
>>> +// Required #define to get clock_gettime() & strdup
>>> +#define _POSIX_C_SOURCE 200809L
>>> +#include <time.h>
>>> +#include <string.h>
>>> +
>>> +#include <unistd.h>
>>> +
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +
>>> +#include "zunitc/zunitc_impl.h"
>>> +#include "zunitc/zunitc.h"
>>> +
>>> +
>>> +#if _POSIX_MONOTONIC_CLOCK
>>> +static const clockid_t TARGET_TIMER = CLOCK_MONOTONIC;
>>> +#else
>>> +static const clockid_t TARGET_TIMER = CLOCK_REALTIME;
>>> +#endif
>>> +
>>> +typedef struct ZucTest
>>> +{
>>> +	zucimpl_test_fn fn;
>>> +	char *caseName;
>>> +	char *testName;
>>> +	int failed;
>>> +	int disabled;
>>> +	long elapsed;
>>> +
>>> +	struct ZucTest *next;
>>> +} ZucTest;
>>> +
>>> +typedef struct ZucCase
>>> +{
>>> +	char *caseName;
>>> +	long elapsed;
>>> +	int testCount;
>>> +	ZucTest *firstTest;
>>> +
>>> +	struct ZucCase *next;
>>> +} ZucCase;
>>> +
>>> +
>>> +static char const DISABLED_PREFIX[] = "DISABLED_";
>>> +
>>> +// Data structure simple, but should suffice for smaller numbers of tests.
>>> +static int caseListCount = 0;
>>> +static ZucCase *caseListHead = NULL;
>>> +
>>> +static int gBad = 0;
>>> +
>>> +static ZucCase *gCurrCase = NULL;
>>> +static ZucTest *gCurrTest = NULL;
>>> +
>>> +
>>> +static ZucCase *getCase(char const *caseName);
>>> +
>>> +static void attachTest(ZucTest *test);
>>> +
>>> +static void countLiveTests(int *caseCount, int *testCount, int *disabledCount);
>>> +
>>> +static void countLiveTestsForCase(ZucCase const *testCase,
>>> +				  int *testCount, int *disabledCount);
>>> +
>>> +
>>> +ZucCase *getCase(char const *caseName)
>>> +{
>>> +	ZucCase *foundCase = NULL;
>>> +	if (caseName)
>>> +	{
>>> +		ZucCase *currCase;
>>> +		for (currCase = caseListHead; currCase && !foundCase;
>>> +		     currCase = currCase->next)
>>> +		{
>>> +			if (strcmp(currCase->caseName, caseName) == 0)
>>> +			{
>>> +				foundCase = currCase;
>>> +			}
>>> +		}
>>> +	}
>>> +	return foundCase;
>>> +}
>>> +
>>> +void zucimpl_add_test(zucimpl_test_fn testFn,
>>> +		      char const *caseName, char const *testName)
>>> +{
>>> +	ZucTest *test = (ZucTest *)malloc(sizeof(ZucTest));
>>> +	if (test) {
>>> +		memset(test, 0, sizeof(ZucTest));
>>
>> calloc
>>
>>> +		test->fn = testFn;
>>> +		test->caseName = strdup(caseName);
>>> +		test->testName = strdup(testName);
>>> +		if (!testFn ||
>>> +		    (strncmp(DISABLED_PREFIX,
>>> +			     testName, sizeof(DISABLED_PREFIX) - 1) == 0))
>>> +		{
>>> +			test->disabled = 1;
>>> +		}
>>> +
>>> +		attachTest(test);
>>> +	} else {
>>> +		fprintf(stderr, "%s:%d: error unable to allocate memory.\n",
>>> +			__FILE__, __LINE__);
>>> +	}
>>> +}
>>> +
>>> +void attachTest(ZucTest *test)
>>> +{
>>> +	if (test) {
>>> +		ZucCase *testCase = getCase(test->caseName);
>>> +		if (!testCase)
>>> +		{
>>> +			// Need to add a new case to hold the test
>>> +			testCase = (ZucCase *)malloc(sizeof(ZucCase));
>>> +			memset(testCase, 0, sizeof(ZucCase));
>> calloc
>>
>>> +			testCase->caseName = strdup(test->caseName);
>>> +
>>> +			if (caseListHead) {
>>> +				ZucCase *curr = caseListHead;
>>> +				while (curr && curr->next) {
>>> +					curr = curr->next;
>>> +				}
>>> +				curr->next = testCase;
>>> +			} else {
>>> +				caseListHead = testCase;
>>> +			}
>>> +			caseListCount++;
>>> +		}
>>> +
>>> +		if (testCase->firstTest) {
>>> +			ZucTest *curr = testCase->firstTest;
>>> +			while (curr && curr->next) {
>>> +				curr = curr->next;
>>> +			}
>>> +			curr->next = test;
>>> +		} else {
>>> +			testCase->firstTest = test;
>>> +		}
>>> +		testCase->testCount++;
>>> +	}
>>> +}
>>>
>>> +void zucimpl_run_tests(void)
>>> +{
>>> +	printf("Running tests...\n");
>>> +
>>> +	int liveCaseCount = 0;
>>> +	int liveTestCount = 0;
>>> +	int disabledCount = 0;
>>> +	countLiveTests(&liveCaseCount, &liveTestCount, &disabledCount);
>>> +
>>> +	printf("[==========] Running %d %s from %d test %s.\n",
>>> +	       liveTestCount,
>>> +	       (liveTestCount == 1) ? "test" : "tests",
>>> +	       liveCaseCount,
>>> +	       (liveCaseCount == 1) ? "case" : "cases");
>>> +
>>> +	long totalElapsed = 0;
>>> +	int totalPassed = 0;
>>> +	int totalFailed = 0;
>>> +	gBad = 0;
>>> +	ZucCase *currCase;
>>> +	for (currCase = caseListHead; currCase; currCase = currCase->next)
>>> +	{
>>> +		gCurrCase = currCase;
>>> +
>>> +		int countXX = 0;
>>> +		countLiveTestsForCase(currCase, &countXX, NULL);
>>> +		if (countXX)
>>> +		{
>>> +			printf("[----------] %d %s from %s.\n",
>>> +			       countXX,
>>> +			       (countXX == 1) ? "test" : "tests",
>>> +			       currCase->caseName);
>>> +
>>> +			ZucTest *curr;
>>> +			for (curr = currCase->firstTest; curr;
>>> +			     curr = curr->next)
>>> +			{
>>> +				if (!curr->disabled)
>>> +				{
>>> +					gCurrTest = curr;
>>> +					printf("[ RUN      ] %s:%s\n",
>>> +					       curr->caseName, curr->testName);
>>> +					struct timespec begin;
>>> +					memset(&begin, 0, sizeof(begin));
>>> +					clock_gettime(TARGET_TIMER, &begin);
>>> +
>>> +					curr->fn();
>>> +
>>> +					if (curr->failed)
>>> +					{
>>> +						totalFailed++;
>>> +					} else {
>>> +						totalPassed++;
>>> +					}
>>> +
>>> +					struct timespec end;
>>> +					memset(&end, 0, sizeof(end));
>>> +					clock_gettime(TARGET_TIMER, &end);
>>> +					// tv_sec, tv_nsec
>>> +
>>> +					long elapsed =
>>> +						(end.tv_sec - begin.tv_sec)
>>> +						* 1000L;
>>> +					if (end.tv_sec != begin.tv_sec) {
>>> +						elapsed -= (begin.tv_nsec)
>>> +							/ 1000000L;
>>> +						elapsed += (end.tv_nsec)
>>> +							/ 1000000L;
>>> +					} else {
>>> +						elapsed +=
>>> +							(end.tv_nsec
>>> +							 - begin.tv_nsec)
>>> +							/ 1000000L;
>>
>>> +					}
>>> +					curr->elapsed = elapsed;
>>> +					currCase->elapsed += elapsed;
>>> +
>>> +					if (curr->failed)
>>> +					{
>>> +						printf("[  FAILED  ] %s:%s (%ld ms)\n",curr->caseName, curr->testName, curr->elapsed);
>>> +					}
>>> +					else
>>> +					{
>>> +						printf("[       OK ] %s:%s (%ld ms)\n", curr->caseName, curr->testName, curr->elapsed);
>>> +					}
>>
>> Since all the other args are the same in both cases, maybe just mush it together:
>>
>> 					printf("[ %-8s] %s:%s (%ld ms)\n", (curr->failed)?"OK":"FAILED", curr->caseName, curr->testName, curr->elapsed);
>>
>>> +					gCurrTest = NULL;
>>> +				}
>>> +			}
>>> +
>>> +			totalElapsed += currCase->elapsed;
>>> +			printf("[----------] %d %s from %s (%ld ms)\n",
>>> +			       currCase->testCount,
>>> +			       (currCase->testCount == 1) ? "test" : "tests",
>>> +			       currCase->caseName,
>>> +			       currCase->elapsed);
>>> +			printf("\n");
>>> +		}
>>> +		gCurrCase = NULL;
>>> +	}
>>> +	printf("[==========] %d %s from %d test %s ran. (%ld ms)\n",
>>> +	       liveTestCount,
>>> +	       (liveTestCount == 1) ? "test" : "tests",
>>> +	       liveCaseCount,
>>> +	       (liveCaseCount == 1) ? "case" : "cases",
>>> +	       totalElapsed);
>>
>> You can probably condense the following code by eliminating brackets.
>>
>>> +	if (totalPassed) {
>>> +		printf("[  PASSED  ] %d %s.\n", totalPassed, (totalPassed == 1) ? "test" : "tests");
>>> +	}
>>> +
>>> +	if (totalFailed) {
>>> +		printf("[  FAILED  ] %d %s, listed below:\n",
>>> +		       totalFailed, (totalFailed == 1) ? "test" : "tests");
>>> +
>>> +		for (currCase = caseListHead; currCase; currCase = currCase->next)
>>> +		{
>>> +			ZucTest *curr;
>>> +			for (curr = currCase->firstTest; curr; curr = curr->next)
>>> +			{
>>> +				if (curr->failed) {
>>> +					printf("[  FAILED  ] %s.%s\n", currCase->caseName, curr->testName);
>>> +				}
>>> +			}
>>> +		}
>>> +	}
>>
>> Brackets are unnecessary for the following three if statements:
>>
>>> +	if (totalFailed || disabledCount)
>>> +	{
>>> +		printf("\n");
>>> +	}
>>> +
>>> +	if (totalFailed)
>>> +	{
>>> +		printf(" %d FAILED %s\n",
>>> +		       totalFailed,
>>> +		       (totalFailed == 1) ? "TEST" : "TESTS");
>>> +	}
>>> +
>>> +	if (disabledCount)
>>> +	{
>>> +		printf("  YOU HAVE %d DISABLED %s\n",
>>> +		       disabledCount,
>>> +		       (disabledCount == 1) ? "TEST" : "TESTS");
>>> +	}
>>> +}
>>> +
>>> +int zucimpl_testFailed()
>>> +{
>>> +	int failed = gBad;
>>> +	if (gCurrTest) {
>>> +		failed = gCurrTest->failed;
>>> +	}
>>> +	return failed;
>>> +}
>>
>> No need for failed var:
>>
>> int zucimpl_testFailed()
>> {
>> 	if (gCurrTest)
>> 		return gCurrTest->failed;
>> 	return gBad;
>> }
>>
>> Similarly through the following routines; just return 0 or 1 when the
>> failure status is determined.
>>
>> If you don't like this approach, and want to retained a status variable
>> returned at function end, that's fine but maybe call it 'has_failed' or
>> even just 'status'.  I have to think a moment to realize "failed == 0"
>> means non-failing.
>>
>>> +
>>> +static void markFailed(void)
>>> +{
>>> +	gBad = 1;
>>> +	if (gCurrTest) {
>>> +		gCurrTest->failed = 1;
>>> +	}
>>> +}
>>> +
>>> +int zucimpl_expect_true(int condition, char const *file, int line, const char *valueStr){
>>> +	int failed = 0;
>>> +	if (!condition)
>>> +	{
>>> +		printf("%s:%d: error: Value of: %s\n", file, line, valueStr);
>>> +		printf("  Actual: %d\n", condition);
>>> +		printf("Expected: TRUE\n");
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_false(int condition, char const *file, int line, const char *valueStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (condition)
>>> +	{
>>> +		printf("%s:%d: error: Value of: %s\n", file, line, valueStr);
>>> +		printf("  Actual: %d\n", condition);
>>> +		printf("Expected: FALSE\n");
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_eq(int expected, int actual, char const *file, int line, const char *valueStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (expected != actual)
>>> +	{
>>> +		printf("%s:%d: error: Value of: %s\n", file, line, valueStr);
>>> +		printf("  Actual: %d\n", actual);
>>> +		printf("Expected: %d\n", expected);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_ne(int expected, int actual, char const *file, int line, const char *valueStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (expected == actual)
>>> +	{
>>> +		printf("%s:%d: error: ", file, line);
>>
>> Your results output format differs for this and following functions
>> compared with the above.
>>
>> Also, makes me wonder if it's worth moving the printfs to a common
>> helper function to better enforce consistency?
>>
>>> +		printf("Expected: (%d) != (%s), actual %d vs %d\n", expected, valueStr, expected, actual);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_lt(int lhs, int rhs, char const *file, int line, const char *lhsStr, const char* rhsStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (lhs >= rhs)
>>> +	{
>>> +		printf("%s:%d: error: ", file, line);
>>> +		printf("Expected: (%s) < (%s), actual %d vs %d\n", lhsStr, rhsStr, lhs, rhs);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_le(int lhs, int rhs, char const *file, int line, const char *lhsStr, const char* rhsStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (lhs > rhs)
>>> +	{
>>> +		printf("%s:%d: error: ", file, line);
>>> +		printf("Expected: (%s) <= (%s), actual %d vs %d\n", lhsStr, rhsStr, lhs, rhs);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_gt(int lhs, int rhs, char const *file, int line, const char *lhsStr, const char* rhsStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (lhs <= rhs)
>>> +	{
>>> +		printf("%s:%d: error: ", file, line);
>>> +		printf("Expected: (%s) > (%s), actual %d vs %d\n", lhsStr, rhsStr, lhs, rhs);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +int zucimpl_expect_ge(int lhs, int rhs, char const *file, int line, const char *lhsStr, const char* rhsStr)
>>> +{
>>> +	int failed = 0;
>>> +	if (lhs < rhs)
>>> +	{
>>> +		printf("%s:%d: error: ", file, line);
>>> +		printf("Expected: (%s) >= (%s), actual %d vs %d\n", lhsStr, rhsStr, lhs, rhs);
>>> +		failed = 1;
>>> +		markFailed();
>>> +	}
>>> +	return failed;
>>> +}
>>> +
>>> +void countLiveTestsForCase(ZucCase const *testCase, int *testCount, int *disabledCount)
>>> +{
>>> +	int localTestCount = 0;
>>> +	int localSkippedCount = 0;
>>> +	ZucTest *curr;
>>> +	for (curr = testCase->firstTest; curr; curr = curr->next)
>>> +	{
>>> +		if (curr->disabled)
>>> +		{
>>> +			localSkippedCount++;
>>> +		}
>>> +		else
>>> +		{
>>> +			localTestCount++;
>>> +		}
>>> +	}
>>> +
>>> +	if (testCount)
>>> +	{
>>> +		*testCount = localTestCount;
>>> +	}
>>> +
>>> +	if (disabledCount)
>>> +	{
>>> +		*disabledCount = localSkippedCount;
>>> +	}
>>> +}
>>> +
>>> +void countLiveTests(int *caseCount, int *testCount, int *disabledCount)
>>> +{
>>> +	int localCaseCount = 0;
>>> +	int localTestCount = 0;
>>> +	int localSkippedCount = 0;
>>> +
>>> +	ZucCase *currCase;
>>> +	for (currCase = caseListHead; currCase; currCase = currCase->next)
>>> +	{
>>> +		int liveInCase = 0;
>>> +		int skippedInCase = 0;
>>> +		countLiveTestsForCase(currCase, &liveInCase, &skippedInCase);
>>> +		localSkippedCount += skippedInCase;
>>> +		localTestCount += liveInCase;
>>> +		if (liveInCase)
>>> +		{
>>> +			localCaseCount++;
>>> +		}
>>> +	}
>>> +
>>> +	if (caseCount)
>>> +	{
>>> +		*caseCount = localCaseCount;
>>> +	}
>>> +
>>> +	if (testCount)
>>> +	{
>>> +		*testCount = localTestCount;
>>> +	}
>>> +
>>> +	if (disabledCount)
>>> +	{
>>> +		*disabledCount = localSkippedCount;
>>> +	}
>>> +}
>>> diff --git a/tools/zunitc/test/zunitc_test.c b/tools/zunitc/test/zunitc_test.c
>>> new file mode 100644
>>> index 0000000..813b72f
>>> --- /dev/null
>>> +++ b/tools/zunitc/test/zunitc_test.c
>>> @@ -0,0 +1,106 @@
>>> +/*
>>> + * Copyright © 2015 Samsung Electronics Co., Ltd
>>> + *
>>> + * Permission to use, copy, modify, distribute, and sell this software and
>>> + * its documentation for any purpose is hereby granted without fee, provided
>>> + * that the above copyright notice appear in all copies and that both that
>>> + * copyright notice and this permission notice appear in supporting
>>> + * documentation, and that the name of the copyright holders not be used in
>>> + * advertising or publicity pertaining to distribution of the software
>>> + * without specific, written prior permission.  The copyright holders make
>>> + * no representations about the suitability of this software for any
>>> + * purpose.  It is provided "as is" without express or implied warranty.
>>> + *
>>> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
>>> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
>>> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
>>> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
>>> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
>>> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
>>> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>>> + */
>>> +
>>> +/*
>>> + * A simple file to show tests being setup and run.
>>> + */
>>> +
>>> +#include "config.h"
>>> +
>>> +#include <unistd.h>
>>> +#include <stdio.h>
>>> +
>>> +
>>> +
>>> +#include "zunitc/zunitc.h"
>>> +
>>> +ZUC_TEST(BaseTest, MathIsSane)
>>> +{
>>> +	ZUC_EXPECT_EQ(4, 2 + 2);
>>> +}
>>> +
>>> +ZUC_TEST(BaseTest, MathIsHard)
>>> +{
>>> +#ifdef ENABLE_FAIL_TESTS
>>> +	ZUC_EXPECT_EQ(5, 2 + 2);
>>> +	ZUC_EXPECT_EQ(7, 9);
>>> +#endif
>>> +}
>>> +
>>> +ZUC_TEST(BaseTest, MathIsMoreHard)
>>> +{
>>> +#ifdef ENABLE_FAIL_TESTS
>>> +	ZUC_ASSERT_EQ(5, 2 + 2);
>>> +	ZUC_ASSERT_EQ(7, 9);
>>> +#endif
>>> +}
>>> +
>>> +ZUC_TEST(OtherTest, MathMonkey)
>>> +{
>>> +	ZUC_EXPECT_TRUE(1);
>>> +	ZUC_EXPECT_TRUE(3);
>>> +	ZUC_EXPECT_FALSE(0);
>>> +
>>> +	ZUC_ASSERT_TRUE(1);
>>> +	ZUC_ASSERT_TRUE(3);
>>> +	ZUC_ASSERT_FALSE(0);
>>> +
>>> +	ZUC_EXPECT_EQ(5, 2 + 3);
>>> +	ZUC_ASSERT_EQ(5, 2 + 3);
>>> +
>>> +	int b = 9;
>>> +	ZUC_EXPECT_NE(1, 2);
>>> +	ZUC_EXPECT_NE(b, b + 2);
>>> +
>>> +	ZUC_ASSERT_NE(1, 2);
>>> +	ZUC_ASSERT_NE(b, b + 1);
>>> +
>>> +	ZUC_EXPECT_LT(1, 2);
>>> +	ZUC_ASSERT_LT(1, 3);
>>> +
>>> +	ZUC_EXPECT_LE(1, 2);
>>> +	ZUC_ASSERT_LE(1, 3);
>>> +
>>> +	ZUC_EXPECT_LE(1, 1);
>>> +	ZUC_ASSERT_LE(1, 1);
>>> +
>>> +	ZUC_EXPECT_GT(2, 1);
>>> +	ZUC_ASSERT_GT(3, 1);
>>> +
>>> +	ZUC_EXPECT_GE(1, 1);
>>> +	ZUC_ASSERT_GE(1, 1);
>>> +
>>> +	ZUC_EXPECT_GE(2, 1);
>>> +	ZUC_ASSERT_GE(3, 1);
>>> +}
>>> +
>>> +int main( int argc, const char* argv[] )
>>> +{
>>> +	ZUC_ADD_TEST(BaseTest, MathIsSane);
>>> +	ZUC_ADD_TEST(BaseTest, MathIsHard);
>>> +	ZUC_ADD_TEST(BaseTest, MathIsMoreHard);
>>> +	ZUC_ADD_TEST(OtherTest, MathMonkey);
>>> +
>>> +	ZUC_RUN_TESTS();
>>> +
>>> +	return 0;
>>> +}
>>> -- 
>>> 2.1.0
>>>
>>> _______________________________________________
>>> wayland-devel mailing list
>>> wayland-devel at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 



More information about the wayland-devel mailing list