* This file contains all the definitions of the functions related with\r
* the tesh runner type.\r
*\r
- */\r
+ */ \r
#include <runner.h>\r
#include <units.h>\r
#include <unit.h>\r
#include <xerrno.h>\r
#include <variable.h>\r
-\r
+ \r
#include <errno.h> /* for error code */\r
#include <stdlib.h> /* for calloc() */\r
#include <stdio.h>\r
-\r
+ \r
#include <readline.h>\r
#include <explode.h>\r
-\r
-#ifndef WIN32\r
+ \r
+#ifndef _XBT_WIN32\r
#include <sys/resource.h>\r
-#endif\r
-\r
-\r
-\r
-\r
-\r
+#endif /* \r */
+ \r\r\r\r\r
#define _RUNNER_HASHCODE 0xFEFEAAAA \r
-\r
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
-\r
-#if (!defined(__BUILTIN) && defined(__CHKCMD) && !defined(WIN32))\r
-static const char* builtin[] =\r
-{\r
- "alias",\r
- "bind",\r
- "builtin",\r
- "caller",\r
- "cd",\r
- "command",\r
- "compgen",\r
- "complete",\r
- "declare",\r
- "disown",\r
- "echo",\r
- "enable",\r
- "eval",\r
- "exec",\r
- "export",\r
- "false",\r
- "fc",\r
- "function",\r
- "getopts",\r
- "hash",\r
- "history",\r
- "jobs",\r
- "let",\r
- "logout",\r
- "printf",\r
- "pwd",\r
- "readonly",\r
- "shift",\r
- "shopt",\r
- "source",\r
- "suspend",\r
- "test",\r
- "time",\r
- "times",\r
- "trap",\r
- "true",\r
- "type",\r
- "typeset",\r
- "ulimit",\r
- "umask",\r
- "unalias",\r
- "unset",\r
- NULL\r
-};\r
-\r
+ \rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
+\r\r
+#if (!defined(__BUILTIN) && defined(__CHKCMD) && !defined(_XBT_WIN32))\r
+static const char *builtin[] = \r
+ { \r"alias", \r"bind", \r"builtin", \r"caller", \r"cd", \r"command",
+\r"compgen", \r"complete", \r"declare", \r"disown", \r"echo", \r"enable", \r"eval", \r"exec", \r"export",
+\r"false", \r"fc", \r"function", \r"getopts", \r"hash", \r"history", \r"jobs", \r"let", \r"logout",
+\r"printf", \r"pwd", \r"readonly", \r"shift", \r"shopt", \r"source", \r"suspend", \r"test", \r"time",
+\r"times", \r"trap", \r"true", \r"type", \r"typeset", \r"ulimit", \r"umask", \r"unalias", \r"unset",
+\rNULL \r
+};
+
+\r\r
#define __BUILTIN_MAX ((size_t)42)\r
-#endif\r
-\r
-\r
+#endif /* \r */
+ \r\r
# ifdef __APPLE__\r
-/* under darwin, the environment gets added to the process at startup time. So, it's not defined at library link time, forcing us to extra tricks */\r
+/* under darwin, the environment gets added to the process at startup time. So, it's not defined at library link time, forcing us to extra tricks */ \r
# include <crt_externs.h>\r
# define environ (*_NSGetEnviron())\r
-# elif !defined(WIN32)\r
- /* the environment, as specified by the opengroup, used to initialize the process properties */\r
- extern char **environ;\r
+# else\r
+#ifdef _XBT_WIN32\r
+ /* the environment, as specified by the opengroup, used to initialize the process properties */ \r
+# define environ **wenviron;\r
+#else /* \r */
+extern char **environ;
+\r
+#endif /* \r */
# endif\r
+ \r
+#ifndef _XBT_WIN32\r
+extern char **\r environ;
\r
-#ifndef WIN32\r
-extern char**\r
-environ;\r
-#endif\r
-\r
-/* the unique tesh runner */\r
-static runner_t\r
-runner = NULL;\r
-\r
-/* wait for the tesh runner terminaison */\r
-static void\r
-runner_wait(void);\r
-\r
-static void*\r
-runner_start_routine(void* p);\r
-\r
-\r
+#endif /* \r */
+ \r
+/* the unique tesh runner */ \r
+static runner_t \r runner = NULL;
+\r\r
+/* wait for the tesh runner terminaison */ \r
+static void \r runner_wait(void);
+\r\rstatic void *\r runner_start_routine(void *p);
+\r\r\r
/* check the syntax of the tesh files if \r
* the check_syntax_flag is specified. Returns\r
* 0 if the syntax is clean.\r
- */\r
+ */ \r
/*static void\r
-check_syntax(void);*/\r
-\r
-#ifdef WIN32\r
-\r
-static HANDLE \r
-timer_handle = NULL;\r
-\r
-\r
-static void*\r
-runner_start_routine(void* p)\r
-{\r
- \r
- LARGE_INTEGER li;\r
-\r
- li.QuadPart=- runner->timeout * 10000000; /* 10000000 = 10 000 000 * 100 nanoseconds = 1 second */\r
-\r
- /* create the waitable timer */\r
- timer_handle = CreateWaitableTimer(NULL, TRUE, NULL);\r
-\r
- /* set a timer to wait for timeout seconds */\r
- SetWaitableTimer(timer_handle, &li, 0, NULL, NULL, 0);\r
+check_syntax(void);*/ \r
\r
- /* wait for the timer */\r
- WaitForSingleObject(timer_handle, INFINITE);\r
-\r
- if(runner->waiting)\r
- {\r
- exit_code = ELEADTIME;\r
- err_kind = 1;\r
- runner->timeouted = 1;\r
- xbt_os_sem_release(units_sem);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-#else\r
-static void*\r
-runner_start_routine(void* p)\r
-{\r
- struct timespec ts;\r
- int timeout = runner->timeout;\r
- \r
- \r
- while(timeout-- && runner->waiting)\r
- {\r
- ts.tv_sec = 1;\r
- ts.tv_nsec = 0L;\r
-\r
- do\r
- {\r
- nanosleep(&ts, &ts);\r
- }while(EINTR == errno);\r
- }\r
- \r
- if(errno)\r
- {\r
- /* TODO process the error */\r
- }\r
- else\r
- {\r
- if(runner->waiting)\r
- {\r
- exit_code = ELEADTIME;\r
- err_kind = 1;\r
- runner->timeouted = 1;\r
- xbt_os_sem_release(units_sem);\r
- }\r
- }\r
- \r
- return NULL;\r
-}\r
-#endif\r
-\r
-\r
-int\r
-runner_init(/*int check_syntax_flag, */int timeout, fstreams_t fstreams)\r
-{\r
- \r
- int i;\r
- char* val;\r
- char buffer[PATH_MAX + 1] = {0};\r
-\r
- int code;\r
- const char* cstr;\r
- variable_t variable;\r
- \r
- #if (defined(__CHKCMD) && defined(__BUILTIN) && !defined(WIN32))\r
- FILE* s;\r
- int n = 0;\r
- size_t len;\r
- char* line = NULL;\r
- int is_blank;\r
- #endif\r
- \r
- \r
- if(runner)\r
- {\r
- ERROR0("The runner is already initialized");\r
- return -1;\r
- }\r
- \r
- runner = xbt_new0(s_runner_t, 1);\r
- \r
- runner->path = NULL;\r
- runner->builtin = NULL;\r
- \r
- if(!(runner->units = units_new(runner, fstreams)))\r
- {\r
- free(runner);\r
- runner = NULL;\r
- return -1;\r
- }\r
-\r
- runner->timeout = timeout;\r
- runner->timeouted = 0;\r
- runner->interrupted = 0;\r
- runner->number_of_ended_units = 0;\r
- runner->number_of_runned_units = 0;\r
- runner->waiting = 0;\r
- \r
- runner->total_of_tests = 0;\r
- runner->total_of_successeded_tests = 0;\r
- runner->total_of_failed_tests = 0;\r
- runner->total_of_interrupted_tests = 0;\r
- \r
- runner->total_of_units = 0;\r
- runner->total_of_successeded_units = 0;\r
- runner->total_of_failed_units = 0;\r
- runner->total_of_interrupted_units = 0;\r
- \r
- runner->total_of_suites = 0;\r
- runner->total_of_successeded_suites = 0;\r
- runner->total_of_failed_suites = 0;\r
- runner->total_of_interrupted_suites = 0;\r
- \r
- /* initialize the vector of variables */\r
- runner->variables = xbt_dynar_new(sizeof(variable_t), (void_f_pvoid_t)variable_free);\r
- \r
- /* add the environment variables in the vector */\r
- for(i = 0; environ[i] != NULL; i++)\r
- {\r
- val = strchr(environ[i], '=');\r
- \r
- if(val)\r
- {\r
- val++;\r
- \r
- if(val[0] != '\0')\r
- strncpy(buffer, environ[i], (val - environ[i] -1));\r
- \r
- if(!strcmp("TESH_PPID", buffer))\r
- is_tesh_root = 0;\r
- \r
- variable = variable_new(buffer, val);\r
- variable->env = 1;\r
- xbt_dynar_push(runner->variables, &variable);\r
- \r
- #ifndef WIN32\r
- if(!strcmp("PATH", buffer))\r
- #else\r
- if(!strcmp("Path", buffer) || !strcmp("PATH", buffer))\r
- #endif\r
- {\r
- char* p;\r
- size_t j,k, len;\r
- \r
- /* get the list of paths */\r
- \r
- #ifdef WIN32\r
- runner->path = explode(';', val);\r
- #else\r
- runner->path = explode(':', val);\r
- #endif\r
-\r
- /* remove spaces and backslahes at the end of the path */\r
- for (k = 0; runner->path[k] != NULL; k++)\r
- {\r
- p = runner->path[k];\r
- \r
- len = strlen(p);\r
- \r
- #ifndef WIN32\r
- for(j = len - 1; p[j] == '/' || p[j] == ' '; j--)\r
- #else\r
- for(j = len - 1; p[j] == '\\' || p[j] == ' '; j--)\r
- #endif\r
- p[j] = '\0';\r
- }\r
- }\r
- \r
- \r
- memset(buffer, 0, PATH_MAX + 1);\r
- }\r
- }\r
- \r
- if(is_tesh_root)\r
- {\r
- char* tesh_dir = getcwd(NULL, 0);\r
- \r
- sprintf(buffer,"%d",getpid());\r
- \r
- #ifndef WIN32\r
- setenv("TESH_PPID", buffer, 0);\r
- setenv("TESH_DIR", tesh_dir, 0);\r
- #else\r
- SetEnvironmentVariable("TESH_PPID", buffer);\r
- SetEnvironmentVariable("TESH_DIR", tesh_dir);\r
- #endif\r
- \r
- variable = variable_new("TESH_PPID", buffer);\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
-\r
- variable = variable_new("TESH_DIR", tesh_dir);\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
- \r
- free(tesh_dir);\r
- }\r
- \r
- variable = variable_new("EXIT_SUCCESS", "0");\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
-\r
- variable = variable_new("EXIT_FAILURE", "1");\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
-\r
- variable = variable_new("TRUE", "0");\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
-\r
- variable = variable_new("FALSE", "1");\r
- variable->err = 1;\r
- \r
- xbt_dynar_push(runner->variables, &variable);\r
-\r
- i = 0;\r
- \r
- /* add the errors variables */\r
- while((cstr = error_get_at(i++, &code)))\r
- {\r
- sprintf(buffer,"%d",code);\r
- variable = variable_new(cstr, buffer);\r
- variable->err = 1;\r
- xbt_dynar_push(runner->variables, &variable);\r
- }\r
- \r
- /* if the user want check the syntax, check it */\r
- /*if(check_syntax_flag)\r
- check_syntax();\r
- */\r
- \r
- #if (!defined(WIN32) && defined(__CHKCMD))\r
- #if defined(__BUILTIN)\r
- \r
- if(!is_tesh_root)\r
- {\r
- /* compute the full path the builtin.def file */\r
- sprintf(buffer,"%s/builtin.def",getenv("TESH_DIR"));\r
- \r
- if(!(s = fopen(buffer, "r"))) \r
- {\r
- ERROR1("File `(%s)' not found", buffer);\r
- return -1;\r
- }\r
- \r
- }\r
- else\r
- {\r
- if(!(s = fopen("builtin.def", "r"))) \r
- {\r
- ERROR0("File `(builtin.def)' not found");\r
- return -1;\r
- }\r
- }\r
- \r
- if(s)\r
- {\r
- fpos_t begin;\r
-\r
- fgetpos(s, &begin);\r
-\r
- while(readline(s, &line, &len) != -1)\r
- {\r
- i = 0;\r
- is_blank = 1;\r
- \r
-\r
- while(line[i] != '\0') \r
- {\r
- if (line[i] != ' ' && line[i] != '\t' && line[i]!='\n' && line[i]!='\r')\r
- {\r
- is_blank = 0;\r
- break;\r
- }\r
- \r
- i++;\r
- }\r
-\r
- if(!is_blank)\r
- n++;\r
- }\r
-\r
- fsetpos(s, &begin);\r
- free(line);\r
- line = NULL;\r
-\r
- if(n)\r
- {\r
- char* l;\r
- \r
- runner->builtin = xbt_new0(char*, n + 1); /* (char**) calloc(n + 1, sizeof(char*));*/\r
- \r
- n = 0;\r
- \r
- while(readline(s, &line, &len) != -1)\r
- {\r
- i = 0;\r
- is_blank = 1;\r
-\r
- while(line[i] != '\0') \r
- {\r
- if (line[i] != ' ' && line[i] != '\t' && line[i]!='\n' && line[i]!='\r')\r
- {\r
- is_blank = 0;\r
- break;\r
- }\r
- \r
- i++;\r
- }\r
-\r
- if(!is_blank)\r
- {\r
- l = strdup(line);\r
-\r
- l[strlen(l) - 1] = '\0';\r
-\r
- (runner->builtin)[n++] = l;\r
- \r
- }\r
- }\r
- \r
- }\r
- else\r
- {\r
- WARN0("The file `(builtin.def)' is empty");\r
- free(runner->builtin);\r
- runner->builtin = NULL;\r
- }\r
- \r
-\r
- fclose(s);\r
- \r
- if(line)\r
- free(line);\r
- \r
- }\r
- \r
- #else\r
- runner->builtin = xbt_new0(char*, __BUILTIN_MAX + 1); /* (char**) calloc(__BUILTIN_MAX + 1, sizeof(char*));*/\r
- \r
- for(i = 0; i < __BUILTIN_MAX; i++)\r
- runner->builtin[i] = strdup(builtin[i]); \r
- #endif\r
- #endif\r
-\r
- return exit_code ? -1 : 0;\r
-}\r
-\r
-void\r
-runner_destroy(void)\r
-{\r
- int i;\r
- \r
- if(runner->units)\r
- units_free((void**)(&(runner->units)));\r
- \r
- if(runner->variables)\r
- xbt_dynar_free(&runner->variables);\r
- \r
- #ifdef WIN32\r
- CloseHandle(timer_handle);\r
- #endif\r
-\r
- if(runner->thread)\r
- xbt_os_thread_join(runner->thread, NULL);\r
- \r
- if(runner->path)\r
- {\r
- for (i = 0; runner->path[i] != NULL; i++)\r
- free(runner->path[i]);\r
- \r
- free(runner->path);\r
- }\r
-\r
- if(runner->builtin)\r
- {\r
- for (i = 0; runner->builtin[i] != NULL; i++)\r
- free(runner->builtin[i]);\r
- \r
- free(runner->builtin);\r
- }\r
-\r
- free(runner);\r
- \r
-\r
- runner = NULL;\r
-}\r
-\r
-void\r
-runner_run(void)\r
-{\r
- /* allocate the mutex used by the units to asynchronously access \r
- * to the properties of the runner.\r
- */\r
- xbt_os_mutex_t mutex = xbt_os_mutex_init();\r
- \r
- /* run all the units */\r
- units_run_all(runner->units, mutex);\r
- \r
- \r
- if(!interrupted)\r
- runner_wait();\r
-\r
- \r
- /* if the runner is timeouted or receive a interruption request\r
- * , interrupt all the active units.\r
- */\r
- if(runner->timeouted || interrupted)\r
- runner_interrupt();\r
- \r
- /* joins all the units */\r
- units_join_all(runner->units);\r
- \r
- /* release the mutex resource */\r
- xbt_os_mutex_destroy(mutex);\r
-\r
-}\r
-\r
-static void\r
-runner_wait(void)\r
-{\r
- if(runner->timeout > 0)\r
- runner->thread = xbt_os_thread_create("", runner_start_routine, NULL);\r
- \r
- /* signal that the runner is waiting */\r
- runner->waiting = 1;\r
- \r
- /* wait for the end of all the units */\r
- xbt_os_sem_acquire(units_sem);\r
-\r
- \r
- runner->waiting = 0;\r
-}\r
-\r
-\r
-\r
+#ifdef _XBT_WIN32\r
+\rstatic HANDLE \r timer_handle = NULL;
+\r\r\rstatic void *\r runner_start_routine(void *p) \r
+{
+ \r\rLARGE_INTEGER li;
+ \r\rli.QuadPart = -runner->timeout * 10000000; /* 10000000 = 10 000 000 * 100 nanoseconds = 1 second */
+ \r\r
+ /* create the waitable timer */ \r
+ timer_handle = CreateWaitableTimer(NULL, TRUE, NULL);
+ \r\r
+ /* set a timer to wait for timeout seconds */ \r
+ SetWaitableTimer(timer_handle, &li, 0, NULL, NULL, 0);
+ \r\r
+ /* wait for the timer */ \r
+ WaitForSingleObject(timer_handle, INFINITE);
+ \r\rif (runner->waiting)
+ \r {
+ \rexit_code = ELEADTIME;
+ \rerr_kind = 1;
+ \rrunner->timeouted = 1;
+ \rxbt_os_sem_release(units_sem);
+ \r}
+ \r\rreturn NULL;
+\r}
+
+\r\r
+#else /* \r */
+static void *\r runner_start_routine(void *p) \r
+{
+ \rstruct timespec ts;
+ \rint timeout = runner->timeout;
+ \r\r\rwhile (timeout-- && runner->waiting)
+ \r {
+ \rts.tv_sec = 1;
+ \rts.tv_nsec = 0L;
+ \r\r
+ do
+ \r {
+ \rnanosleep(&ts, &ts);
+ \r} while (EINTR == errno);
+ \r}
+ \r\rif (errno)
+ \r {
+ \r
+ /* TODO process the error */ \r
+ }
+ \r
+ else
+ \r {
+ \rif (runner->waiting)
+ \r {
+ \rexit_code = ELEADTIME;
+ \rerr_kind = 1;
+ \rrunner->timeouted = 1;
+ \rxbt_os_sem_release(units_sem);
+ \r}
+ \r}
+ \r\rreturn NULL;
+\r}
+
+\r
+#endif /* \r */
+\r\rint \r
+runner_init( /*int check_syntax_flag, */ int timeout,
+ fstreams_t fstreams) \r
+{
+ \r\rint i;
+ \rchar *val;
+ \rchar buffer[PATH_MAX + 1] = { 0 };
+ \r\rint code;
+ \rconst char *cstr;
+ \rvariable_t variable;
+ \r\r
+#if (defined(__CHKCMD) && defined(__BUILTIN) && !defined(_XBT_WIN32))\r
+ FILE * s;
+ \rint n = 0;
+ \rsize_t len;
+ \rchar *line = NULL;
+ \rint is_blank;
+ \r
+#endif /* \r */
+ \r\rif (runner)
+ \r {
+ \rERROR0("The runner is already initialized");
+ \rreturn -1;
+ \r}
+ \r\rrunner = xbt_new0(s_runner_t, 1);
+ \r\rrunner->path = NULL;
+ \rrunner->builtin = NULL;
+ \r\rif (!(runner->units = units_new(runner, fstreams)))
+ \r {
+ \rfree(runner);
+ \rrunner = NULL;
+ \rreturn -1;
+ \r}
+ \r\rrunner->timeout = timeout;
+ \rrunner->timeouted = 0;
+ \rrunner->interrupted = 0;
+ \rrunner->number_of_ended_units = 0;
+ \rrunner->number_of_runned_units = 0;
+ \rrunner->waiting = 0;
+ \r\rrunner->total_of_tests = 0;
+ \rrunner->total_of_successeded_tests = 0;
+ \rrunner->total_of_failed_tests = 0;
+ \rrunner->total_of_interrupted_tests = 0;
+ \r\rrunner->total_of_units = 0;
+ \rrunner->total_of_successeded_units = 0;
+ \rrunner->total_of_failed_units = 0;
+ \rrunner->total_of_interrupted_units = 0;
+ \r\rrunner->total_of_suites = 0;
+ \rrunner->total_of_successeded_suites = 0;
+ \rrunner->total_of_failed_suites = 0;
+ \rrunner->total_of_interrupted_suites = 0;
+ \r\r
+ /* initialize the vector of variables */ \r
+ runner->variables =
+ xbt_dynar_new(sizeof(variable_t), (void_f_pvoid_t) variable_free);
+ \r\r
+ /* add the environment variables in the vector */ \r
+ for (i = 0; environ[i] != NULL; i++)
+ \r {
+ \rval = strchr(environ[i], '=');
+ \r\rif (val)
+ \r {
+ \rval++;
+ \r\rif (val[0] != '\0')
+ \rstrncpy(buffer, environ[i], (val - environ[i] - 1));
+ \r\rif (!strcmp("TESH_PPID", buffer))
+ \ris_tesh_root = 0;
+ \r\rvariable = variable_new(buffer, val);
+ \rvariable->env = 1;
+ \rxbt_dynar_push(runner->variables, &variable);
+ \r\r
+#ifndef _XBT_WIN32\r
+ if (!strcmp("PATH", buffer))
+ \r
+#else /* \r */
+ if (!strcmp("Path", buffer) || !strcmp("PATH", buffer))
+ \r
+#endif /* \r */
+ {
+ \rchar *p;
+ \rsize_t j, k, len;
+ \r\r
+ /* get the list of paths */ \r
+ \r
+#ifdef _XBT_WIN32\r
+ runner->path = explode(';', val);
+ \r
+#else /* \r */
+ runner->path = explode(':', val);
+ \r
+#endif /* \r */
+ \r
+ /* remove spaces and backslahes at the end of the path */ \r
+ for (k = 0; runner->path[k] != NULL; k++)
+ \r {
+ \rp = runner->path[k];
+ \r\rlen = strlen(p);
+ \r\r
+#ifndef _XBT_WIN32\r
+ for (j = len - 1; p[j] == '/' || p[j] == ' '; j--)
+ \r
+#else /* \r */
+ for (j = len - 1; p[j] == '\\' || p[j] == ' '; j--)
+ \r
+#endif /* \r */
+ p[j] = '\0';
+ \r}
+ \r}
+ \r\r\rmemset(buffer, 0, PATH_MAX + 1);
+ \r}
+ \r}
+ \r\rif (is_tesh_root)
+ \r {
+ \rchar *tesh_dir = getcwd(NULL, 0);
+ \r\rsprintf(buffer, "%d", getpid());
+ \r\r
+#ifndef _XBT_WIN32\r
+ setenv("TESH_PPID", buffer, 0);
+ \rsetenv("TESH_DIR", tesh_dir, 0);
+ \r
+#else /* \r */
+ SetEnvironmentVariable("TESH_PPID", buffer);
+ \rSetEnvironmentVariable("TESH_DIR", tesh_dir);
+ \r
+#endif /* \r */
+ \rvariable = variable_new("TESH_PPID", buffer);
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\rvariable = variable_new("TESH_DIR", tesh_dir);
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\rfree(tesh_dir);
+ \r}
+ \r\rvariable = variable_new("EXIT_SUCCESS", "0");
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\rvariable = variable_new("EXIT_FAILURE", "1");
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\rvariable = variable_new("TRUE", "0");
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\rvariable = variable_new("FALSE", "1");
+ \rvariable->err = 1;
+ \r\rxbt_dynar_push(runner->variables, &variable);
+ \r\ri = 0;
+ \r\r
+ /* add the errors variables */ \r
+ while ((cstr = error_get_at(i++, &code)))
+ \r {
+ \rsprintf(buffer, "%d", code);
+ \rvariable = variable_new(cstr, buffer);
+ \rvariable->err = 1;
+ \rxbt_dynar_push(runner->variables, &variable);
+ \r}
+ \r\r
+ /* if the user want check the syntax, check it */ \r
+ /*if(check_syntax_flag)\r
+ check_syntax();\r
+ */ \r
+ \r
+#if (!defined(_XBT_WIN32) && defined(__CHKCMD))\r
+#if defined(__BUILTIN)\r
+ \rif (!is_tesh_root)
+ \r {
+ \r
+ /* compute the full path the builtin.def file */ \r
+ sprintf(buffer, "%s/builtin.def", getenv("TESH_DIR"));
+ \r\rif (!(s = fopen(buffer, "r")))
+ \r {
+ \rERROR1("File `(%s)' not found", buffer);
+ \rreturn -1;
+ \r}
+ \r\r}
+ \r
+ else
+ \r {
+ \rif (!(s = fopen("builtin.def", "r")))
+ \r {
+ \rERROR0("File `(builtin.def)' not found");
+ \rreturn -1;
+ \r}
+ \r}
+ \r\rif (s)
+ \r {
+ \rfpos_t begin;
+ \r\rfgetpos(s, &begin);
+ \r\rwhile (readline(s, &line, &len) != -1)
+ \r {
+ \ri = 0;
+ \ris_blank = 1;
+ \r\r\rwhile (line[i] != '\0')
+ \r {
+ \rif (line[i] != ' ' && line[i] != '\t' && line[i] != '\n'
+ && line[i] != '\r')
+ \r {
+ \ris_blank = 0;
+ \rbreak;
+ \r}
+ \r\ri++;
+ \r}
+ \r\rif (!is_blank)
+ \rn++;
+ \r}
+ \r\rfsetpos(s, &begin);
+ \rfree(line);
+ \rline = NULL;
+ \r\rif (n)
+ \r {
+ \rchar *l;
+ \r\rrunner->builtin = xbt_new0(char *, n + 1); /* (char**) calloc(n + 1, sizeof(char*)); */
+ \r\rn = 0;
+ \r\rwhile (readline(s, &line, &len) != -1)
+ \r {
+ \ri = 0;
+ \ris_blank = 1;
+ \r\rwhile (line[i] != '\0')
+ \r {
+ \rif (line[i] != ' ' && line[i] != '\t' && line[i] != '\n'
+ && line[i] != '\r')
+ \r {
+ \ris_blank = 0;
+ \rbreak;
+ \r}
+ \r\ri++;
+ \r}
+ \r\rif (!is_blank)
+ \r {
+ \rl = strdup(line);
+ \r\rl[strlen(l) - 1] = '\0';
+ \r\r(runner->builtin)[n++] = l;
+ \r\r}
+ \r}
+ \r\r}
+ \r
+ else
+ \r {
+ \rWARN0("The file `(builtin.def)' is empty");
+ \rfree(runner->builtin);
+ \rrunner->builtin = NULL;
+ \r}
+ \r\r\rfclose(s);
+ \r\rif (line)
+ \rfree(line);
+ \r\r}
+ \r\r
+#else /* \r */
+ runner->builtin = xbt_new0(char *, __BUILTIN_MAX + 1); /* (char**) calloc(__BUILTIN_MAX + 1, sizeof(char*)); */
+ \r\rfor (i = 0; i < __BUILTIN_MAX; i++)
+ \rrunner->builtin[i] = strdup(builtin[i]);
+ \r
+#endif /* \r */
+#endif /* \r */
+ \rreturn exit_code ? -1 : 0;
+\r}
+
+\r\rvoid \r runner_destroy(void) \r
+{
+ \rint i;
+ \r\rif (runner->units)
+ \runits_free((void **) (&(runner->units)));
+ \r\rif (runner->variables)
+ \rxbt_dynar_free(&runner->variables);
+ \r\r
+#ifdef _XBT_WIN32\r
+ CloseHandle(timer_handle);
+ \r
+#endif /* \r */
+ \rif (runner->thread)
+ \rxbt_os_thread_join(runner->thread, NULL);
+ \r\rif (runner->path)
+ \r {
+ \rfor (i = 0; runner->path[i] != NULL; i++)
+ \rfree(runner->path[i]);
+ \r\rfree(runner->path);
+ \r}
+ \r\rif (runner->builtin)
+ \r {
+ \rfor (i = 0; runner->builtin[i] != NULL; i++)
+ \rfree(runner->builtin[i]);
+ \r\rfree(runner->builtin);
+ \r}
+ \r\rfree(runner);
+ \r\r\rrunner = NULL;
+\r}
+
+\r\rvoid \r runner_run(void) \r
+{
+ \r
+ /* allocate the mutex used by the units to asynchronously access \r
+ * to the properties of the runner.\r
+ */ \r
+ xbt_os_mutex_t mutex = xbt_os_mutex_init();
+ \r\r
+ /* run all the units */ \r
+ units_run_all(runner->units, mutex);
+ \r\r\rif (!interrupted)
+ \rrunner_wait();
+ \r\r\r
+ /* if the runner is timeouted or receive a interruption request\r
+ * , interrupt all the active units.\r
+ */ \r
+ if (runner->timeouted || interrupted)
+ \rrunner_interrupt();
+ \r\r
+ /* joins all the units */ \r
+ units_join_all(runner->units);
+ \r\r
+ /* release the mutex resource */ \r
+ xbt_os_mutex_destroy(mutex);
+\r\r}
+
+\r\rstatic void \r runner_wait(void) \r
+{
+ \rif (runner->timeout > 0)
+ \rrunner->thread = xbt_os_thread_create("", runner_start_routine, NULL);
+ \r\r
+ /* signal that the runner is waiting */ \r
+ runner->waiting = 1;
+ \r\r
+ /* wait for the end of all the units */ \r
+ xbt_os_sem_acquire(units_sem);
+ \r\r\rrunner->waiting = 0;
+\r}
+
+\r\r\r\r
/*\r
* interrupt all the active units.\r
* this function is called when the lead time of the execution is reached\r
* or when a failed unit requests an interruption of the execution.\r
- */\r
-void\r
-runner_interrupt(void)\r
-{\r
- units_interrupt_all(runner->units);\r
-}\r
-\r
-void\r
-runner_summarize(void)\r
-{\r
- \r
- if(!dry_run_flag)\r
- {\r
- #ifndef WIN32\r
- struct rusage r_usage;\r
- #else\r
- FILETIME start_time;\r
- FILETIME exit_time;\r
- FILETIME kernel_time;\r
- FILETIME user_time;\r
- SYSTEMTIME si;\r
- #endif\r
- \r
- printf("\n TEst SHell utility - mini shell specialized in running test units.\n");\r
- printf(" =============================================================================\n");\r
- \r
- units_summuarize(runner->units);\r
- \r
- printf(" =====================================================================%s\n",\r
- runner->total_of_failed_tests ? "== FAILED": (runner->total_of_interrupted_tests || runner->total_of_interrupted_units) ? "==== INTR" : "====== OK");\r
- \r
- printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",\r
- (runner->total_of_suites ? (1-((double)runner->total_of_failed_suites + (double)runner->total_of_interrupted_suites)/(double)runner->total_of_suites)*100.0 : 100.0),\r
- runner->total_of_suites, runner->total_of_successeded_suites);\r
- \r
- if(runner->total_of_failed_suites > 0)\r
- printf(", %d failed", runner->total_of_failed_suites);\r
- \r
- if(runner->total_of_interrupted_suites > 0)\r
- printf(", %d interrupted)", runner->total_of_interrupted_suites);\r
- \r
- printf(")\n"); \r
- \r
- printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",\r
- (runner->total_of_units ? (1-((double)runner->total_of_failed_units + (double)runner->total_of_interrupted_units)/(double)runner->total_of_units)*100.0 : 100.0),\r
- runner->total_of_units, runner->total_of_successeded_units);\r
- \r
- if(runner->total_of_failed_units > 0)\r
- printf(", %d failed", runner->total_of_failed_units);\r
- \r
- if(runner->total_of_interrupted_units > 0)\r
- printf(", %d interrupted)", runner->total_of_interrupted_units);\r
- \r
- printf(")\n");\r
- \r
- printf(" Test(s): %.0f%% ok (%d test(s): %d ok",\r
- (runner->total_of_tests ? (1-((double)runner->total_of_failed_tests + (double)runner->total_of_interrupted_tests)/(double)runner->total_of_tests)*100.0 : 100.0),\r
- runner->total_of_tests, runner->total_of_successeded_tests);\r
- \r
- if(runner->total_of_failed_tests > 0)\r
- printf(", %d failed", runner->total_of_failed_tests);\r
- \r
- if(runner->total_of_interrupted_tests > 0)\r
- printf(", %d interrupted)", runner->total_of_interrupted_tests);\r
- \r
- printf(")\n\n");\r
- \r
- #ifndef WIN32\r
- if(!getrusage(RUSAGE_SELF, &r_usage))\r
- {\r
- \r
- printf(" Total tesh user time used: %ld second(s) %ld microsecond(s)\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);\r
- printf(" Total tesh system time used: %ld second(s) %ld microsecond(s)\n\n", r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);\r
- \r
- if(!getrusage(RUSAGE_CHILDREN, &r_usage))\r
- {\r
- printf(" Total children user time used: %ld second(s) %ld microsecond(s)\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);\r
- printf(" Total children system time used: %ld second(s) %ld microsecond(s)\n\n", r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);\r
- \r
- } \r
- }\r
- #else\r
- \r
- if(GetProcessTimes(GetCurrentProcess(), &start_time, &exit_time, &kernel_time, &user_time))\r
- {\r
- FileTimeToSystemTime(&user_time, &si);\r
- \r
- printf(" Total tesh user time used: %uhour(s) %uminute(s) %usecond(s) %millisecond(s)\n", si.wHour, si.wMinute, si.wSecond, si.wMilliseconds );\r
- \r
- FileTimeToSystemTime(&kernel_time, &si);\r
- \r
- printf(" Total tesh kernel time used: %uhour(s) %uminute(s) %usecond(s) %millisecond(s)\n", si.wHour, si.wMinute, si.wSecond, si.wMilliseconds );\r
- }\r
-\r
-\r
-\r
- #endif\r
- }\r
- else\r
- {\r
- if(exit_code)\r
- ERROR0("Syntax NOK");\r
- else if(!exit_code)\r
- INFO0("Syntax 0K");\r
- }\r
-}\r
-\r
-int\r
-runner_is_timedout(void)\r
-{\r
- return runner->timeouted;\r
-}\r
-\r
+ */ \r
+void \r runner_interrupt(void) \r
+{
+ \runits_interrupt_all(runner->units);
+\r} \r\rvoid \r runner_summarize(void) \r
+{
+ \r\rif (!dry_run_flag)
+ \r {
+ \r
+#ifndef _XBT_WIN32\r
+ struct rusage r_usage;
+ \r
+#else /* \r */
+ FILETIME start_time;
+ \rFILETIME exit_time;
+ \rFILETIME kernel_time;
+ \rFILETIME user_time;
+ \rSYSTEMTIME si;
+ \r
+#endif /* \r */
+ \rprintf
+ ("\n TEst SHell utility - mini shell specialized in running test units.\n");
+ \rprintf
+ (" =============================================================================\n");
+ \r\runits_summuarize(runner->units);
+ \r\rprintf
+ (" =====================================================================%s\n",
+ \rrunner->total_of_failed_tests ? "== FAILED" : (runner->
+ total_of_interrupted_tests
+ || runner->
+ total_of_interrupted_units)
+ ? "==== INTR" : "====== OK");
+ \r\rprintf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
+ \r(runner->
+ total_of_suites ? (1 -
+ ((double) runner->
+ total_of_failed_suites +
+ (double) runner->
+ total_of_interrupted_suites) /
+ (double) runner->total_of_suites) *
+ 100.0 : 100.0), \rrunner->total_of_suites,
+ runner->total_of_successeded_suites);
+ \r\rif (runner->total_of_failed_suites > 0)
+ \rprintf(", %d failed", runner->total_of_failed_suites);
+ \r\rif (runner->total_of_interrupted_suites > 0)
+ \rprintf(", %d interrupted)", runner->total_of_interrupted_suites);
+ \r\rprintf(")\n");
+ \r\rprintf(" Unit(s): %.0f%% ok (%d unit(s): %d ok", \r
+ (runner->
+ total_of_units ? (1 -
+ ((double) runner->total_of_failed_units +
+ (double) runner->
+ total_of_interrupted_units) /
+ (double) runner->total_of_units) *
+ 100.0 : 100.0), \rrunner->total_of_units,
+ runner->total_of_successeded_units);
+ \r\rif (runner->total_of_failed_units > 0)
+ \rprintf(", %d failed", runner->total_of_failed_units);
+ \r\rif (runner->total_of_interrupted_units > 0)
+ \rprintf(", %d interrupted)", runner->total_of_interrupted_units);
+ \r\rprintf(")\n");
+ \r\rprintf(" Test(s): %.0f%% ok (%d test(s): %d ok", \r
+ (runner->
+ total_of_tests ? (1 -
+ ((double) runner->total_of_failed_tests +
+ (double) runner->
+ total_of_interrupted_tests) /
+ (double) runner->total_of_tests) *
+ 100.0 : 100.0), \rrunner->total_of_tests,
+ runner->total_of_successeded_tests);
+ \r\rif (runner->total_of_failed_tests > 0)
+ \rprintf(", %d failed", runner->total_of_failed_tests);
+ \r\rif (runner->total_of_interrupted_tests > 0)
+ \rprintf(", %d interrupted)", runner->total_of_interrupted_tests);
+ \r\rprintf(")\n\n");
+ \r\r
+#ifndef _XBT_WIN32\r
+ if (!getrusage(RUSAGE_SELF, &r_usage))
+ \r {
+ \r\rprintf
+ (" Total tesh user time used: %ld second(s) %ld microsecond(s)\n",
+ r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);
+ \rprintf
+ (" Total tesh system time used: %ld second(s) %ld microsecond(s)\n\n",
+ r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
+ \r\rif (!getrusage(RUSAGE_CHILDREN, &r_usage))
+ \r {
+ \rprintf
+ (" Total children user time used: %ld second(s) %ld microsecond(s)\n",
+ r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);
+ \rprintf
+ (" Total children system time used: %ld second(s) %ld microsecond(s)\n\n",
+ r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
+ \r\r}
+ \r}
+ \r
+#else /* \r */
+ \rif (GetProcessTimes
+ (GetCurrentProcess(), &start_time, &exit_time, &kernel_time,
+ &user_time))
+ \r {
+ \rFileTimeToSystemTime(&user_time, &si);
+ \r\rprintf
+ (" User time used: %2u Hour(s) %2u Minute(s) %2u Second(s) %3u Millisecond(s)\n",
+ si.wHour, si.wMinute, si.wSecond, si.wMilliseconds);
+ \r\rFileTimeToSystemTime(&kernel_time, &si);
+ \r\rprintf
+ (" Kernel time used: %2u Hour(s) %2u Minute(s) %2u Second(s) %3u Millisecond(s)\n",
+ si.wHour, si.wMinute, si.wSecond, si.wMilliseconds);
+ \r}
+ \r\r\r\r
+#endif /* \r */
+ }
+ \r
+ else
+ \r {
+ \rif (exit_code)
+ \rERROR0("Syntax NOK");
+ \r
+ else if (!exit_code)
+ \rINFO0("Syntax 0K");
+ \r}
+\r}
+
+\r\rint \r runner_is_timedout(void) \r
+{
+ \rreturn runner->timeouted;
+\r}
+
+\r\r