[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