Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Some change concerning the display of the summary
[simgrid.git] / tools / tesh2 / src / runner.c
index ead1a69..79ccc08 100644 (file)
@@ -11,7 +11,6 @@
  *             the tesh runner type.\r
  *\r
  */\r
\r
 #include <runner.h>\r
 #include <units.h>\r
 #include <unit.h>\r
 #include <stdlib.h>    /* for calloc()         */\r
 #include <stdio.h>\r
 \r
+#include <readline.h>\r
+#include <explode.h>\r
+\r
 #ifndef WIN32\r
 #include <sys/resource.h>\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
+#define __BUILTIN_MAX ((size_t)42)\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
+# 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
+# endif\r
+\r
 #ifndef WIN32\r
 extern char**\r
 environ;\r
@@ -51,14 +118,15 @@ runner_start_routine(void* p);
  * the check_syntax_flag is specified. Returns\r
  * 0 if the syntax is clean.\r
  */\r
-static void\r
-check_syntax(void);\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
@@ -75,10 +143,11 @@ runner_start_routine(void* p)
     \r
     /* wait for the timer */\r
     WaitForSingleObject(timer_handle, INFINITE);\r
-       \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
@@ -91,14 +160,19 @@ static void*
 runner_start_routine(void* p)\r
 {\r
        struct timespec ts;\r
-\r
-       ts.tv_sec = runner->timeout;\r
-       ts.tv_nsec = 0L;\r
-\r
-       do\r
+       int timeout = runner->timeout;\r
+       \r
+       \r
+       while(timeout-- && runner->waiting)\r
        {\r
-               nanosleep(&ts, &ts);\r
-       }while(EINTR == errno);\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
@@ -109,6 +183,7 @@ runner_start_routine(void* p)
                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
@@ -120,21 +195,37 @@ runner_start_routine(void* p)
 \r
 \r
 int\r
-runner_init(int check_syntax_flag, int timeout, fstreams_t fstreams)\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
-               return EALREADY;\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
@@ -185,25 +276,92 @@ runner_init(int check_syntax_flag, int timeout, fstreams_t fstreams)
                        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->env = 1;\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
@@ -216,19 +374,137 @@ runner_init(int check_syntax_flag, int timeout, fstreams_t fstreams)
        }\r
        \r
        /* if the user want check the syntax, check it */\r
-       if(check_syntax_flag)\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
-       return exit_code ? -1 : 0;\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
-       units_free((void**)(&(runner->units)));\r
-\r
-       xbt_dynar_free(&runner->variables);\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
@@ -236,6 +512,22 @@ runner_destroy(void)
 \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
@@ -254,8 +546,10 @@ runner_run(void)
        /* 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
@@ -282,6 +576,7 @@ runner_wait(void)
        \r
        /* wait for the end of all the units */\r
        xbt_os_sem_acquire(units_sem);\r
+\r
        \r
        runner->waiting = 0;\r
 }\r
@@ -349,7 +644,7 @@ runner_summarize(void)
                \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
+               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
@@ -379,11 +674,11 @@ runner_summarize(void)
                {\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
+                       printf(" 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
                        \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
+                       printf(" 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
@@ -393,38 +688,15 @@ runner_summarize(void)
        else\r
        {\r
                if(exit_code)\r
-                       ERROR0("Syntax error detected");\r
+                       ERROR0("Syntax NOK");\r
                else if(!exit_code)\r
                        INFO0("Syntax 0K");\r
        }\r
 }\r
 \r
-static void\r
-check_syntax(void)\r
+int\r
+runner_is_timedout(void)\r
 {\r
-       if(!dry_run_flag)\r
-       {\r
-               dry_run_flag = 1;\r
-               \r
-               runner_run();\r
-       \r
-               dry_run_flag = 0;\r
-               \r
-               if(!exit_code)\r
-               {\r
-                       if(!silent_flag)\r
-                               INFO0("syntax checked (OK)");\r
-                       \r
-                       units_reset_all(runner->units);\r
-               \r
-               }\r
-               else\r
-                       errno = exit_code;\r
-               \r
-       }\r
-       else\r
-       {\r
-               WARN0("mismatch in the syntax : --just-check-syntax and --check-syntax options at same time");\r
-       }\r
-\r
+       return runner->timeouted;\r
 }\r
+\r