libcheck: port to latest check git
authorNirbheek Chauhan <nirbheek@centricular.com>
Fri, 9 Dec 2016 09:48:11 +0000 (15:18 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Fri, 9 Dec 2016 10:01:01 +0000 (15:31 +0530)
Upstream seems to have stopped doing releases, but we need to update for better
Windows and Visual Studio support.

This patch only updates the libcheck sources and ignores the compatibility
sources for now.

https://bugzilla.gnome.org/show_bug.cgi?id=775870

18 files changed:
libs/gst/check/libcheck/check.c
libs/gst/check/libcheck/check.h.in
libs/gst/check/libcheck/check_error.c
libs/gst/check/libcheck/check_error.h
libs/gst/check/libcheck/check_impl.h
libs/gst/check/libcheck/check_list.c
libs/gst/check/libcheck/check_list.h
libs/gst/check/libcheck/check_log.c
libs/gst/check/libcheck/check_log.h
libs/gst/check/libcheck/check_msg.c
libs/gst/check/libcheck/check_msg.h
libs/gst/check/libcheck/check_pack.c
libs/gst/check/libcheck/check_pack.h
libs/gst/check/libcheck/check_print.c
libs/gst/check/libcheck/check_print.h
libs/gst/check/libcheck/check_run.c
libs/gst/check/libcheck/check_str.c
libs/gst/check/libcheck/check_str.h

index 5a50d7d..5b8c434 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <string.h>
 #include <stdio.h>
@@ -52,6 +52,8 @@ int check_major_version = CHECK_MAJOR_VERSION;
 int check_minor_version = CHECK_MINOR_VERSION;
 int check_micro_version = CHECK_MICRO_VERSION;
 
+const char* current_test_name = NULL;
+
 static int non_pass (int val);
 static Fixture *fixture_create (SFun fun, int ischecked);
 static void tcase_add_fixture (TCase * tc, SFun setup, SFun teardown,
@@ -108,6 +110,7 @@ suite_free (Suite * s)
   free (s);
 }
 
+
 TCase *
 tcase_create (const char *name)
 {
@@ -150,10 +153,48 @@ tcase_create (const char *name)
   tc->ch_sflst = check_list_create ();
   tc->unch_tflst = check_list_create ();
   tc->ch_tflst = check_list_create ();
+  tc->tags = check_list_create ();
 
   return tc;
 }
 
+/*
+ * Helper function to create a list of tags from
+ * a space separated string.
+ */
+List *
+tag_string_to_list (const char *tags_string)
+{
+  List *list;
+  char *tags;
+  char *tag;
+
+  list = check_list_create ();
+
+  if (NULL == tags_string) {
+    return list;
+  }
+
+  tags = strdup (tags_string);
+  tag = strtok (tags, " ");
+  while (tag) {
+    check_list_add_end (list, strdup (tag));
+    tag = strtok (NULL, " ");
+  }
+  free (tags);
+  return list;
+}
+
+void
+tcase_set_tags (TCase * tc, const char *tags_orig)
+{
+  /* replace any pre-existing list */
+  if (tc->tags) {
+    check_list_apply (tc->tags, free);
+    check_list_free (tc->tags);
+  }
+  tc->tags = tag_string_to_list (tags_orig);
+}
 
 static void
 tcase_free (TCase * tc)
@@ -163,20 +204,44 @@ tcase_free (TCase * tc)
   check_list_apply (tc->ch_sflst, free);
   check_list_apply (tc->unch_tflst, free);
   check_list_apply (tc->ch_tflst, free);
+  check_list_apply (tc->tags, free);
   check_list_free (tc->tflst);
   check_list_free (tc->unch_sflst);
   check_list_free (tc->ch_sflst);
   check_list_free (tc->unch_tflst);
   check_list_free (tc->ch_tflst);
-
+  check_list_free (tc->tags);
   free (tc);
 }
 
+unsigned int
+tcase_matching_tag (TCase * tc, List * check_for)
+{
+
+  if (NULL == check_for) {
+    return 0;
+  }
+
+  for (check_list_front (check_for); !check_list_at_end (check_for);
+      check_list_advance (check_for)) {
+    for (check_list_front (tc->tags); !check_list_at_end (tc->tags);
+        check_list_advance (tc->tags)) {
+      if (0 == strcmp ((const char *) check_list_val (tc->tags),
+              (const char *) check_list_val (check_for))) {
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
 void
 suite_add_tcase (Suite * s, TCase * tc)
 {
-  if (s == NULL || tc == NULL)
+  if (s == NULL || tc == NULL || check_list_contains (s->tclst, tc)) {
     return;
+  }
+
   check_list_add_end (s->tclst, tc);
 }
 
@@ -268,15 +333,23 @@ tcase_set_timeout (TCase * tc, double timeout)
   eprintf
       ("This version does not support timeouts, as fork is not supported",
       __FILE__, __LINE__);
+  /* Ignoring, as Check is not compiled with fork support. */
 #endif /* HAVE_FORK */
 }
 
 void
-tcase_fn_start (const char *fname CK_ATTRIBUTE_UNUSED, const char *file,
-    int line)
+tcase_fn_start (const char *fname, const char *file, int line)
 {
   send_ctx_info (CK_CTX_TEST);
   send_loc_info (file, line);
+  current_test_name = fname;
+}
+
+const char *
+tcase_name ()
+{
+  return current_test_name;
 }
 
 void
@@ -291,17 +364,26 @@ _ck_assert_failed (const char *file, int line, const char *expr, ...)
   const char *msg;
   va_list ap;
   char buf[BUFSIZ];
+  const char *to_send;
 
   send_loc_info (file, line);
 
   va_start (ap, expr);
   msg = (const char *) va_arg (ap, char *);
 
-  if (msg == NULL)
-    msg = expr;
-  vsnprintf (buf, BUFSIZ, msg, ap);
+  /*
+   * If a message was passed, format it with vsnprintf.
+   * Otherwise, print the expression as is.
+   */
+  if (msg != NULL) {
+    vsnprintf (buf, BUFSIZ, msg, ap);
+    to_send = buf;
+  } else {
+    to_send = expr;
+  }
+
   va_end (ap);
-  send_failure_info (buf);
+  send_failure_info (to_send);
   if (cur_fork_status () == CK_FORK) {
 #if defined(HAVE_FORK) && HAVE_FORK==1
     _exit (1);
index 996be7b..9da7fd5 100644 (file)
@@ -1,7 +1,7 @@
 /*-*- mode:C; -*- */
 /*
  * Check: a unit test framework for C
- * Copyright (C) 2001, 2002, Arien Malec
+ * Copyright (C) 2001, 2002 Arien Malec
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_H
@@ -134,7 +134,10 @@ CK_DLL_EXP Suite *CK_EXPORT suite_create (const char *name);
 CK_DLL_EXP int CK_EXPORT suite_tcase (Suite * s, const char *tcname);
 
 /**
- * Add a test case to a suite
+ * Add a test case to a suite.
+ *
+ * Note that if the TCase has already been added attempting
+ * to add it again will be ignored.
  *
  * @param s suite to add test case to
  * @param tc test case to add to suite
@@ -159,6 +162,18 @@ CK_DLL_EXP void CK_EXPORT suite_add_tcase (Suite * s, TCase * tc);
 CK_DLL_EXP TCase *CK_EXPORT tcase_create (const char *name);
 
 /**
+ * Associate a test case with certain tags.
+ * Replaces any existing tags with the new set.
+ *
+ * @param tc the test case
+ *
+ * @param tags string containing arbitrary tags separated by spaces.
+ *        This will be copied. Passing NULL clears all tags.
+ *
+ * @since 0.11.0
+ * */
+CK_DLL_EXP void CK_EXPORT tcase_set_tags (TCase * tc, const char *tags);
+/**
  * Add a test function to a test case
  *
  * @param tc test case to add test to
@@ -330,6 +345,9 @@ CK_DLL_EXP void CK_EXPORT tcase_add_checked_fixture (TCase * tc, SFun setup,
  * the environment variable CK_DEFAULT_TIMEOUT is defined and no timeout
  * is set, the value in the environment variable is used.
  *
+ * If Check is compile without fork() support this call is ignored,
+ * as timeouts are not possible.
+ *
  * @param tc test case to assign timeout to
  * @param timeout to use, in seconds. If the value contains a decimal
  *                 portion, but no high resolution timer is available,
@@ -938,8 +956,9 @@ CK_DLL_EXP void CK_EXPORT srunner_free (SRunner * sr);
  * In addition to running all suites, if the suite runner has been
  * configured to output to a log, that is also performed.
  *
- * Note that if the CK_RUN_CASE and/or CK_RUN_SUITE environment variables
- * are defined, then only the named suite and/or test case is run.
+ * Note that if the CK_RUN_CASE, CK_RUN_SUITE, CK_INCLUDE_TAGS and/or
+ * CK_EXCLUDE_TAGS environment variables are defined, then only the
+ * named suites or test cases will run.
  *
  * @param sr suite runner to run all suites from
  * @param print_mode the verbosity in which to report results to stdout
@@ -957,9 +976,22 @@ CK_DLL_EXP void CK_EXPORT srunner_run_all (SRunner * sr,
  * suite runner has been configured to output to a log, that is also
  * performed.
  *
+ * Note that if the sname and tcname parameters are passed as null
+ * then the function will fallback to using the environment variables
+ * CK_RUN_SUITE and CK_RUN_CASE respectively in order to select the
+ * suite/cases.
+ * 
+ * Similarly if the CK_INCLUDE_TAGS and/or CK_EXCLUDE_TAGS environment
+ * variables are defined then these will further filter the test cases
+ * (see srunner_run_tagged, below).
+ *
  * @param sr suite runner where the given suite or test case must be
- * @param sname suite name to run. A NULL means "any suite".
- * @param tcname test case name to run. A NULL means "any test case"
+ * @param sname suite name to run. A NULL means use the value of the
+ * environment variable CK_RUN_SUITE if set, otherwise run "any/every
+ * suite".
+ * @param tcname test case name to run. A NULL means use the value of
+ * the environment variable CK_RUN_CASE if set, otherwise run
+ * "any/every case".
  * @param print_mode the verbosity in which to report results to stdout
  *
  * @since 0.9.9
@@ -969,6 +1001,45 @@ CK_DLL_EXP void CK_EXPORT srunner_run (SRunner * sr, const char *sname,
 
 
 /**
+ * Run a specific suite or test case or testcases with specific tags
+ * from a suite runner, printing results to stdout as specified by the
+ * print_mode.
+ *
+ * In addition to running any applicable suites or test cases, if the
+ * suite runner has been configured to output to a log, that is also
+ * performed.
+ *
+ * Note that if sname, tcname, include_tags, exclude_tags parameters
+ * are passed as NULL then if the environment variables CK_RUN_SUITE,
+ * CK_RUN_CASE, CK_INCLUDE_TAGS, CK_EXCLUDE_TAGS are defined then these
+ * values will be used instead.
+ *
+ * @param sr suite runner where the given suite or test case must be
+ * @param sname suite name to run. A NULL means use the value of the
+ * environment variable CK_RUN_SUITE if set, otherwise run "any/every
+ * suite".
+ * @param tcname test case name to run. A NULL means use the value of
+ * the environment variable CK_RUN_CASE if set, otherwise run
+ * "any/every case".
+ * @param include_tags space separate list of tags. Only run test
+ * cases that share one of these tags. A NULL means use the value of
+ * the environment variable CK_INCLUDE_TAGS if set, otherwise run
+ * "any/every test case".
+ * @param exclude_tags space separate list of tags. Only run test
+ * cases that do not share one of these tags even if they are selected
+ * by an included tag. A NULL means use the value of the environment
+ * variable CK_EXCLUDE_TAGS if set, otherwise run "any/every test
+ * case".
+ * @param print_mode the verbosity in which to report results to stdout
+ *
+ * @since 0.11.0
+ */
+CK_DLL_EXP void CK_EXPORT srunner_run_tagged (SRunner * sr, const char *sname,
+    const char *tcname,
+    const char *include_tags,
+    const char *exclude_tags, enum print_output print_mode);
+
+/**
  * Retrieve the number of failed tests executed by a suite runner.
  *
  * This value represents both test failures and errors.
@@ -1194,6 +1265,9 @@ CK_DLL_EXP enum fork_status CK_EXPORT srunner_fork_status (SRunner * sr);
  * If set to CK_FORK or CK_NOFORK, the environment variable
  * if defined is ignored.
  *
+ * If Check is compiled without support for fork(), attempting
+ * to set the status to CK_FORK is ignored.
+ *
  * @param sr suite runner to assign the fork status to
  * @param fstat fork status to assign
  *
@@ -1212,9 +1286,13 @@ CK_DLL_EXP void CK_EXPORT srunner_set_fork_status (SRunner * sr,
  * the process group will be killed; using this wrapper will prevent
  * orphan processes.
  *
+ * If Check is compiled without fork() support this call simply
+ * return -1 and does nothing.
+ *
  * @return On success, the PID of the child process is returned in
  *          the parent, and 0 is returned in the child.  On failure,
- *          an error will be printed and exit() invoked.
+ *          a value of -1 is returned to the parent process and no
+ *          child process is created.
  *
  * @since 0.9.3
  */
@@ -1228,6 +1306,9 @@ CK_DLL_EXP pid_t CK_EXPORT check_fork (void);
  * exited without error, exit(EXIT_SUCCESS) is invoked; otherwise
  * exit(EXIT_FAILURE) is invoked.
  *
+ * If Check is compiled without support for fork(), this invokes
+ * exit(EXIT_FAILURE).
+ *
  * @param pid process to wait for, created by check_fork()
  *
  * @since 0.9.3
index 9ee1dd1..8f293aa 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdarg.h>
 #include <stdlib.h>
index 771a7fd..f325fc6 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef ERROR_H
 #define ERROR_H
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 #include <setjmp.h>
 
 extern jmp_buf error_jmp_buffer;
index e5ca7e9..16adfc7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Check: a unit test framework for C
- * Copyright (C) 2001,2002 Arien Malec
+ * Copyright (C) 2001, 2002 Arien Malec
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_IMPL_H
@@ -65,6 +65,7 @@ struct TCase
   List *unch_tflst;
   List *ch_sflst;
   List *ch_tflst;
+  List *tags;
 };
 
 typedef struct TestStats
@@ -134,4 +135,7 @@ enum fork_status cur_fork_status (void);
 
 clockid_t check_get_clockid (void);
 
+unsigned int tcase_matching_tag (TCase * tc, List * check_for);
+List *tag_string_to_list (const char *tags_string);
+
 #endif /* CHECK_IMPL_H */
index bce19d8..610a125 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -150,3 +150,15 @@ check_list_apply (List * lp, void (*fp) (void *))
     fp (check_list_val (lp));
 
 }
+
+bool
+check_list_contains (List * lp, void *val)
+{
+  for (check_list_front (lp); !check_list_at_end (lp); check_list_advance (lp)) {
+    if (check_list_val (lp) == val) {
+      return true;
+    }
+  }
+
+  return false;
+}
index 0270115..005361e 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_LIST_H
 #define CHECK_LIST_H
 
+#include <stdbool.h>
+
 typedef struct List List;
 
 /* Create an empty list */
@@ -52,5 +54,8 @@ void check_list_free (List * lp);
 
 void check_list_apply (List * lp, void (*fp) (void *));
 
+/* Return true if the list contains the value, false otherwise */
+bool check_list_contains (List * lp, void *val);
+
 
 #endif /* CHECK_LIST_H */
index ad5bb79..bb81d6b 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdlib.h>
 #include <stdio.h>
index 8578a90..c1936f9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Check: a unit test framework for C
- * Copyright (C) 2001,2002 Arien Malec
+ * Copyright (C) 2001, 2002 Arien Malec
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_LOG_H
index 676c18b..e862c5c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Check: a unit test framework for C
- * Copyright (C) 2001 2002, Arien Malec
+ * Copyright (C) 2001, 2002 Arien Malec
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <sys/types.h>
 #include <stdlib.h>
@@ -174,7 +174,12 @@ construct_test_result (RcvMsg * rmsg, int waserror)
   tr = tr_create ();
 
   if (rmsg->msg != NULL || waserror) {
-    tr->ctx = rmsg->lastctx;
+    if (rmsg->failctx != CK_CTX_INVALID) {
+      tr->ctx = rmsg->failctx;
+    } else {
+      tr->ctx = rmsg->lastctx;
+    }
+
     tr->msg = rmsg->msg;
     rmsg->msg = NULL;
     tr_set_loc_by_ctx (tr, tr->ctx, rmsg);
@@ -257,7 +262,9 @@ open_tmp_file (char **name)
   if (!tmp_dir) {
     tmp_dir = ".";
   }
+
   *name = ck_strdup_printf ("%s/check_XXXXXX", tmp_dir);
+
   if (-1 < (fd = mkstemp (*name))) {
     file = fdopen (fd, "w+b");
     if (0 == unlink (*name) || NULL == file) {
index f84ee8c..b99a757 100644 (file)
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_MSG_NEW_H
index 5119dfc..146a584 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -471,6 +471,8 @@ punpack (FILE * fdes)
     /* Parse one message */
     n = get_result (buf, rmsg);
     nparse -= n;
+    if (nparse < 0)
+      eprintf ("Error in call to get_result", __FILE__, __LINE__ - 3);
     /* Move remaining data in buffer to the beginning */
     memmove (buf, buf + n, nparse);
     /* If EOF has not been seen */
index 7bde267..e73a196 100644 (file)
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_PACK_H
index 4c1a4ad..c94e47c 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -95,32 +95,48 @@ srunner_fprint_results (FILE * file, SRunner * sr, enum print_output print_mode)
 void
 fprint_xml_esc (FILE * file, const char *str)
 {
-  for (; *str != '\0'; str++) {
+  /* The valid XML characters are as follows:
+   *   #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+   * Characters that are outside of ASCII must be encoded. Further, the
+   * following special characters:
+   *   " ' < > &
+   * must be encoded. We assume that the incoming string may be a multibyte
+   * character.
+   */
 
-    switch (*str) {
-
-        /* handle special characters that must be escaped */
-      case '"':
-        fputs ("&quot;", file);
-        break;
-      case '\'':
-        fputs ("&apos;", file);
-        break;
-      case '<':
-        fputs ("&lt;", file);
-        break;
-      case '>':
-        fputs ("&gt;", file);
-        break;
-      case '&':
-        fputs ("&amp;", file);
-        break;
-
-        /* regular characters, print as is */
-      default:
-        fputc (*str, file);
-        break;
+  for (; *str != '\0'; str++) {
+    char next = *str;
+
+    /* handle special characters that must be escaped */
+    if (next == '"' || next == '\'' || next == '<' || next == '>'
+        || next == '&') {
+      switch (next) {
+        case '"':
+          fputs ("&quot;", file);
+          break;
+        case '\'':
+          fputs ("&apos;", file);
+          break;
+        case '<':
+          fputs ("&lt;", file);
+          break;
+        case '>':
+          fputs ("&gt;", file);
+          break;
+        case '&':
+          fputs ("&amp;", file);
+          break;
+      }
+    }
+    /* printable ASCII */
+    else if (next >= ' ' && next <= '~') {
+      fputc (next, file);
+    }
+    /* Non-printable character */
+    else if (next == 0x9 || next == 0xA || next == 0xD || next >= 0x20) {
+      fprintf (file, "&#x%X;", next);
     }
+    /* If it did not get printed, it is not a valid XML character */
   }
 }
 
index f75274b..20c0d22 100644 (file)
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_PRINT_H
index 38d2cf6..e6b6469 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <sys/types.h>
 #include <time.h>
@@ -59,7 +59,9 @@ enum tf_type
 static void srunner_run_init (SRunner * sr, enum print_output print_mode);
 static void srunner_run_end (SRunner * sr, enum print_output print_mode);
 static void srunner_iterate_suites (SRunner * sr,
-    const char *sname, const char *tcname, enum print_output print_mode);
+    const char *sname, const char *tcname,
+    const char *include_tags,
+    const char *exclude_tags, enum print_output print_mode);
 static void srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc);
 static void srunner_add_failure (SRunner * sr, TestResult * tf);
 static TestResult *srunner_run_setup (List * func_list,
@@ -93,11 +95,8 @@ static int waserror (int status, int expected_signal);
 
 static int alarm_received;
 static pid_t group_pid;
-
-#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
-static struct sigaction old_action[3];
-static struct sigaction new_action[3];
-#endif /* HAVE_SIGACTION && HAVE_FORK */
+static struct sigaction sigint_old_action;
+static struct sigaction sigterm_old_action;
 
 static void CK_ATTRIBUTE_UNUSED
 sig_handler (int sig_nr)
@@ -108,26 +107,21 @@ sig_handler (int sig_nr)
       killpg (group_pid, SIGKILL);
       break;
     case SIGTERM:
-    case SIGINT:{
+    case SIGINT:
+    {
       pid_t own_group_pid;
-      int idx;
-      int child_sig;
+      int child_sig = SIGTERM;
 
       if (sig_nr == SIGINT) {
-        idx = 1;
         child_sig = SIGKILL;
-      } else {                  /* if (sig_nr == SIGTERM) */
-
-        idx = 2;
-        child_sig = SIGTERM;
+        sigaction (SIGINT, &sigint_old_action, NULL);
+      } else {
+        sigaction (SIGTERM, &sigterm_old_action, NULL);
       }
 
       killpg (group_pid, child_sig);
 
-      /* Restore old signal handler... */
-      sigaction (sig_nr, &old_action[idx], NULL);
-
-      /* ... and call it. POSIX says that calling killpg(0)
+      /* POSIX says that calling killpg(0)
        * does not necessarily mean to call it on the callers
        * group pid! */
       own_group_pid = getpgrp ();
@@ -164,14 +158,20 @@ srunner_run_end (SRunner * sr, enum print_output CK_ATTRIBUTE_UNUSED print_mode)
 static void
 srunner_iterate_suites (SRunner * sr,
     const char *sname, const char *tcname,
-    enum print_output CK_ATTRIBUTE_UNUSED print_mode)
+    const char *include_tags,
+    const char *exclude_tags, enum print_output CK_ATTRIBUTE_UNUSED print_mode)
 {
+  List *include_tag_lst;
+  List *exclude_tag_lst;
   List *slst;
   List *tcl;
   TCase *tc;
 
   slst = sr->slst;
 
+  include_tag_lst = tag_string_to_list (include_tags);
+  exclude_tag_lst = tag_string_to_list (exclude_tags);
+
   for (check_list_front (slst); !check_list_at_end (slst);
       check_list_advance (slst)) {
     Suite *s = (Suite *) check_list_val (slst);
@@ -191,12 +191,27 @@ srunner_iterate_suites (SRunner * sr,
       if ((tcname != NULL) && (strcmp (tcname, tc->name) != 0)) {
         continue;
       }
+      if (include_tags != NULL) {
+        if (!tcase_matching_tag (tc, include_tag_lst)) {
+          continue;
+        }
+      }
+      if (exclude_tags != NULL) {
+        if (tcase_matching_tag (tc, exclude_tag_lst)) {
+          continue;
+        }
+      }
 
       srunner_run_tcase (sr, tc);
     }
 
     log_suite_end (sr, s);
   }
+
+  check_list_apply (include_tag_lst, free);
+  check_list_apply (exclude_tag_lst, free);
+  check_list_free (include_tag_lst);
+  check_list_free (exclude_tag_lst);
 }
 
 static void
@@ -567,7 +582,11 @@ set_fork_info (TestResult * tr, int status, int signal_expected,
         free (tr->msg);
       }
       tr->msg = exit_msg (exit_status);
-      tr->rtype = CK_FAILURE;   /* normal exit status */
+      if (exit_status == allowed_exit_value) {
+        tr->rtype = CK_FAILURE; /* normal exit status */
+      } else {
+        tr->rtype = CK_FAILURE; /* early exit */
+      }
     }
   }
 }
@@ -649,6 +668,7 @@ srunner_fork_status (SRunner * sr)
       return CK_FORK;
 #else /* HAVE_FORK */
       eprintf ("This version does not support fork", __FILE__, __LINE__);
+      /* Ignoring, as Check is not compiled with fork support. */
       return CK_NOFORK;
 #endif /* HAVE_FORK */
     }
@@ -663,6 +683,8 @@ srunner_set_fork_status (SRunner * sr, enum fork_status fstat)
   /* If fork() is unavailable, do not allow a fork mode to be set */
   if (fstat != CK_NOFORK) {
     eprintf ("This version does not support fork", __FILE__, __LINE__);
+    /* Overriding, as Check is not compiled with fork support. */
+    fstat = CK_NOFORK;
   }
 #endif /* ! HAVE_FORK */
   sr->fstat = fstat;
@@ -677,15 +699,27 @@ srunner_run_all (SRunner * sr, enum print_output print_mode)
 }
 
 void
-srunner_run (SRunner * sr, const char *sname, const char *tcname,
+srunner_run_tagged (SRunner * sr, const char *sname, const char *tcname,
+    const char *include_tags, const char *exclude_tags,
     enum print_output print_mode)
 {
-  /* Get the selected test suite and test case from the
+#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
+  static struct sigaction sigalarm_old_action;
+  static struct sigaction sigalarm_new_action;
+  static struct sigaction sigint_new_action;
+  static struct sigaction sigterm_new_action;
+#endif /* HAVE_SIGACTION && HAVE_FORK */
+
+  /*  Get the selected test suite and test case from the
      environment.  */
   if (!tcname)
     tcname = getenv ("CK_RUN_CASE");
   if (!sname)
     sname = getenv ("CK_RUN_SUITE");
+  if (!include_tags)
+    include_tags = getenv ("CK_INCLUDE_TAGS");
+  if (!exclude_tags)
+    exclude_tags = getenv ("CK_EXCLUDE_TAGS");
 
   if (sr == NULL)
     return;
@@ -694,24 +728,36 @@ srunner_run (SRunner * sr, const char *sname, const char *tcname,
         __FILE__, __LINE__, print_mode);
   }
 #if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
-  memset (&new_action, 0, sizeof new_action);
-  new_action[0].sa_handler = sig_handler;
-  sigaction (SIGALRM, &new_action[0], &old_action[0]);
-  new_action[1].sa_handler = sig_handler;
-  sigaction (SIGINT, &new_action[1], &old_action[1]);
-  new_action[2].sa_handler = sig_handler;
-  sigaction (SIGTERM, &new_action[2], &old_action[2]);
+  memset (&sigalarm_new_action, 0, sizeof (sigalarm_new_action));
+  sigalarm_new_action.sa_handler = sig_handler;
+  sigaction (SIGALRM, &sigalarm_new_action, &sigalarm_old_action);
+
+  memset (&sigint_new_action, 0, sizeof (sigint_new_action));
+  sigint_new_action.sa_handler = sig_handler;
+  sigaction (SIGINT, &sigint_new_action, &sigint_old_action);
+
+  memset (&sigterm_new_action, 0, sizeof (sigterm_new_action));
+  sigterm_new_action.sa_handler = sig_handler;
+  sigaction (SIGTERM, &sigterm_new_action, &sigterm_old_action);
 #endif /* HAVE_SIGACTION && HAVE_FORK */
   srunner_run_init (sr, print_mode);
-  srunner_iterate_suites (sr, sname, tcname, print_mode);
+  srunner_iterate_suites (sr, sname, tcname, include_tags, exclude_tags,
+      print_mode);
   srunner_run_end (sr, print_mode);
 #if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
-  sigaction (SIGALRM, &old_action[0], NULL);
-  sigaction (SIGINT, &old_action[1], NULL);
-  sigaction (SIGTERM, &old_action[2], NULL);
+  sigaction (SIGALRM, &sigalarm_old_action, NULL);
+  sigaction (SIGINT, &sigint_old_action, NULL);
+  sigaction (SIGTERM, &sigterm_old_action, NULL);
 #endif /* HAVE_SIGACTION && HAVE_FORK */
 }
 
+void
+srunner_run (SRunner * sr, const char *sname, const char *tcname,
+    enum print_output print_mode)
+{
+  srunner_run_tagged (sr, sname, tcname, NULL, NULL, print_mode);
+}
+
 pid_t
 check_fork (void)
 {
@@ -748,5 +794,7 @@ check_waitpid_and_exit (pid_t pid CK_ATTRIBUTE_UNUSED)
   exit (EXIT_SUCCESS);
 #else /* HAVE_FORK */
   eprintf ("This version does not support fork", __FILE__, __LINE__);
+  /* Ignoring, as Check is not compiled with fork support. */
+  exit (EXIT_FAILURE);
 #endif /* HAVE_FORK */
 }
index c1a18b7..b2e6407 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
-#include "libcompat.h"
+#include "libcompat/libcompat.h"
 
 #include <stdio.h>
 #include <stdarg.h>
index bc70fb4..f7fdba7 100644 (file)
@@ -14,8 +14,8 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef CHECK_STR_H