Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Kill tesh2 out of the source tree
[simgrid.git] / tools / tesh2 / src / fstream.c
diff --git a/tools/tesh2/src/fstream.c b/tools/tesh2/src/fstream.c
deleted file mode 100644 (file)
index a0b2dd8..0000000
+++ /dev/null
@@ -1,2259 +0,0 @@
-/*\r
- * src/fstream.c - type representing the tesh file stream.\r
- *\r
- * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. \r
- *\r
- * This program is free software; you can redistribute it and/or modify it \r
- * under the terms of the license (GNU LGPL) which comes with this package.\r
- *\r
- * Purpose:\r
- *             This file contains all the definitions of the functions related with\r
- *             the tesh file stream type.\r
- *\r
- */  \r
-    \r
-#include <fstream.h>\r
-#include <xerrno.h>\r
-#include <context.h>\r
-#include <command.h>\r
-#include <unit.h>\r
-#include <str_replace.h>\r
-#include <variable.h>\r
-    \r
-#include <readline.h>\r
-    \r
-#include <is_cmd.h>\r
-#include <getpath.h>\r
-    \r
-#ifndef _XBT_WIN32\r
-#include <xsignal.h>\r
-#endif  /* \r */
-    \r
-#ifdef _XBT_WIN32\r
-static int \r is_w32_cmd(char *cmd, char **path) \r
-{
-  \rsize_t i = 0;
-  \rstruct stat stat_buff = { 0 };
-  \rchar buff[PATH_MAX + 1] = { 0 };
-  \r\r\r\rif (!cmd)
-    \r {
-    \rerrno = EINVAL;
-    \rreturn 0;
-    \r}
-  \r\rif (stat(cmd, &stat_buff) || !S_ISREG(stat_buff.st_mode))
-    \r {
-    \rif (path)
-      \r {
-      \rfor (i = 0; path[i] != NULL; i++)
-        \r {
-        \r
-            /* use Cat.exe on Windows */ \r
-            if (!strcmp(cmd, "cat"))
-          \rcmd[0] = 'C';
-        \r\rsprintf(buff, "%s\\%s", path[i], cmd);
-        \r\rif (!stat(buff, &stat_buff) && S_ISREG(stat_buff.st_mode))
-          \rreturn 1;
-        \r}
-      \r}
-    \r}
-  \r
-  else
-    \rreturn 1;
-  \r\r\rreturn 0;
-\r}
-
-\r
-#endif  /* \r */
-    \r\rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-\r\r\rlong fstream_getline(fstream_t fstream, char **buf, size_t * n)
-{
-  \r\rreturn readline(fstream->stream, buf, n);
-\r\r}
-
-\r\rstatic void \r failure(unit_t unit) \r
-{
-  \rif (!keep_going_unit_flag)
-    \r {
-    \runit_t root = unit->root ? unit->root : unit;
-    \r\rif (!root->interrupted)
-      \r {
-      \r
-          /* the unit interrupted (exit for the loop) */ \r
-          root->interrupted = 1;
-      \r\r
-          /* release the unit */ \r
-          xbt_os_sem_release(root->sem);
-      \r}
-    \r\r
-        /* if the --keep-going option is not specified */ \r
-        if (!keep_going_flag)
-      \r {
-      \rif (!interrupted)
-        \r {
-        \r
-            /* request an global interruption by the runner */ \r
-            interrupted = 1;
-        \r\r
-            /* release the runner */ \r
-            xbt_os_sem_release(units_sem);
-        \r}
-      \r}
-    \r}
-\r}
-
-\r\rfstream_t \r fstream_new(const char *directory, const char *name) \r
-{
-  \rfstream_t fstream;
-  \r\rif (!name)
-    \r {
-    \rerrno = EINVAL;
-    \rreturn NULL;
-    \r}
-  \r\rif (!directory && !strcmp("stdin", name))
-    \r {
-    \rfstream = xbt_new0(s_fstream_t, 1);
-    \rfstream->name = strdup("stdin");
-    \rreturn fstream;
-    \r}
-  \r
-  else if (!directory)
-    \r {
-    \rerrno = EINVAL;
-    \rreturn NULL;
-    \r}
-  \r\rfstream = xbt_new0(s_fstream_t, 1);
-  \r\rif (!(fstream->name = strdup(name)))
-    \r {
-    \rfree(fstream);
-    \rreturn NULL;
-    \r}
-  \r\rif (!(fstream->directory = strdup(directory)))
-    \r {
-    \rfree(fstream->name);
-    \rfree(fstream);
-    \rreturn NULL;
-    \r}
-  \r\rfstream->stream = NULL;
-  \rfstream->unit = NULL;
-  \rfstream->parsed = 0;
-  \r\r\rreturn fstream;
-\r}
-
-\r\rint \r fstream_open(fstream_t fstream) \r
-{
-  \rchar path[PATH_MAX + 1] = { 0 };
-  \r\r
-      /* check the parameter */ \r
-      if (!(fstream))
-    \r {
-    \rerrno = EINVAL;
-    \rreturn -1;
-    \r}
-  \r\rif (!fstream || fstream->stream)
-    \r {
-    \rerrno = EALREADY;
-    \rreturn -1;
-    \r}
-  \r\rif (!strcmp(fstream->name, "stdin"))
-    \r {
-    \rfstream->stream = stdin;
-    \rreturn 0;
-    \r}
-  \r\r
-#ifndef _XBT_WIN32\r
-      sprintf(path, "%s/%s", fstream->directory, fstream->name);
-  \r
-#else   /* \r */
-      sprintf(path, "%s\\%s", fstream->directory, fstream->name);
-  \r
-#endif  /* \r */
-      \rif (!(fstream->stream = fopen(path, "r")))
-    \r {
-    \rreturn -1;
-    \r}
-  \r\rreturn 0;
-\r}
-
-\r\rint \r fstream_close(fstream_t fstream) \r
-{
-  \r
-      /* check the parameter */ \r
-      if (!(fstream) || !strcmp(fstream->name, "stdin"))
-    \r {
-    \rerrno = EINVAL;
-    \rreturn -1;
-    \r}
-  \r\rif (!fstream->stream)
-    \rreturn EBADF;
-  \r\rif (EOF == fclose(fstream->stream))
-    \rreturn -1;
-  \r\rfstream->stream = NULL;
-  \r\rreturn 0;
-\r}
-
-\r\rint \r fstream_free(fstream_t * ptr) \r
-{
-  \r\r
-      /* check the parameter */ \r
-      if (!(*ptr))
-    \r {
-    \rerrno = EINVAL;
-    \rreturn -1;
-    \r}
-  \r\rif (!(*ptr))
-    \rreturn EINVAL;
-  \r\rif ((*ptr)->stream)
-    \rfclose((*ptr)->stream);
-  \r\rif ((*ptr)->name)
-    \rfree((*ptr)->name);
-  \r\rif ((*ptr)->directory)
-    \rfree((*ptr)->directory);
-  \r\rfree(*ptr);
-  \r\r*ptr = NULL;
-  \r\rreturn 0;
-\r\r}
-
-\r\rint \r fstream_parse(fstream_t fstream, xbt_os_mutex_t mutex) \r
-{
-  \rsize_t len;
-  \rchar *line = NULL;
-  \rint line_num = 0;
-  \rchar file_pos[256];
-  \rxbt_strbuff_t buff;
-  \rint buffbegin = 0;
-  \rcontext_t context;
-  \runit_t unit;
-  \r\r
-      /* Count the line length while checking wheather it's blank */ \r
-  int blankline;
-  \rint linelen;
-  \r
-      /* Deal with \ at the end of the line, and call handle_line on result */ \r
-  int to_be_continued;
-  \r\r
-      /* check the parameter */ \r
-      if (!(fstream) || !mutex)
-    \r {
-    \rerrno = EINVAL;
-    \rreturn -1;
-    \r}
-  \r\rbuff = xbt_strbuff_new();
-  \r\rif (!(context = context_new()))
-    \rreturn -1;
-  \r\runit = fstream->unit;
-  \r\r
-      /*while(!(unit->root->interrupted)  && getline(&line, &len, fstream->stream) != -1) */ \r
-      while (!(unit->root->interrupted)
-             && fstream_getline(fstream, &line, &len) != -1)
-    \r {
-    \r\rblankline = 1;
-    \rlinelen = 0;
-    \rto_be_continued = 0;
-    \r\rline_num++;
-    \r\rwhile (line[linelen] != '\0')
-      \r {
-      \rif (line[linelen] != ' ' && line[linelen] != '\t'
-           && line[linelen] != '\n' && line[linelen] != '\r')
-        \rblankline = 0;
-      \r\rlinelen++;
-      \r}
-    \r\rif (blankline)
-      \r {
-      \rif (!context->command_line
-           && (context->input->used || context->output->used))
-        \r {
-        \rsnprintf(file_pos, 256, "%s:%d", fstream->name, line_num);
-        \rERROR1("[%s] Error : no command found in the last chunk of lines",
-                file_pos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, file_pos);
-        \r\rfailure(unit);
-        \rbreak;
-        \r}
-      \r
-      else if (unit->is_running_suite)
-        \r {                     /* it's the end of a suite */
-        \r\runit_t * current_suite =
-            xbt_dynar_get_ptr(unit->suites,
-                              xbt_dynar_length(unit->suites) - 1);
-        \r\rif (!xbt_dynar_length((*current_suite)->includes))
-          \r {
-          \rERROR2("[%s] Malformated suite `(%s)' : include missing",
-                  file_pos, (*current_suite)->description);
-          \r\runit_set_error(*current_suite, ESYNTAX, 1, file_pos);
-          \r\rfailure(unit);
-          \r\r}
-        \r\runit->is_running_suite = 0;
-        \r}
-      \r\rif (context->command_line)
-        \r {
-        \r
-#ifdef _XBT_WIN32\r
-            if (!context->is_not_found)
-          \r {
-          \r
-#endif  /* \r */
-              if (fstream_launch_command(fstream, context, mutex) < 0)
-            \rbreak;
-          \r\r
-#ifdef _XBT_WIN32\r
-          }
-        \r
-#endif  /* \r */
-        }
-      \r\rcontinue;
-      \r}
-    \r\rif (linelen > 1 && line[linelen - 2] == '\\')
-      \r {
-      \rif (linelen > 2 && line[linelen - 3] == '\\')
-        \r {
-        \r
-            /* Damn. Escaped \ */ \r
-            line[linelen - 2] = '\n';
-        \rline[linelen - 1] = '\0';
-        \r}
-      \r
-      else
-        \r {
-        \rto_be_continued = 1;
-        \rline[linelen - 2] = '\0';
-        \rlinelen -= 2;
-        \r\rif (!buff->used)
-          \rbuffbegin = line_num;
-        \r}
-      \r}
-    \r\rif (buff->used || to_be_continued)
-      \r {
-      \rxbt_strbuff_append(buff, line);
-      \r\rif (!to_be_continued)
-        \r {
-        \rsnprintf(file_pos, 256, "%s:%d", fstream->name, buffbegin);
-        \rfstream_lex_line(fstream, context, mutex, file_pos, buff->data);
-        \rxbt_strbuff_empty(buff);
-        \r}
-      \r}
-    \r
-    else
-      \r {
-      \rsnprintf(file_pos, 256, "%s:%d", fstream->name, line_num);
-      \rfstream_lex_line(fstream, context, mutex, file_pos, line);
-      \r}
-    \r}
-  \r\r
-      /* Check that last command of the file ran well */ \r
-      if (context->command_line)
-    \r {
-    \r
-#ifdef _XBT_WIN32\r
-        if (!context->is_not_found)
-      \r {
-      \r
-#endif  /* \r */
-          \rif (fstream_launch_command(fstream, context, mutex) < 0)
-        \rreturn -1;
-      \r\r
-#ifdef _XBT_WIN32\r
-      }
-    \r
-#endif  /* \r */
-    }
-  \r\r
-      /* clear buffers */ \r
-      if (line)
-    \rfree(line);
-  \r\rxbt_strbuff_free(buff);
-  \r\rif (context_free(&context) < 0)
-    \rreturn -1;
-  \r\rreturn (exit_code || errno) ? -1 : 0;
-\r}
-
-\r\r\rvoid \r
-fstream_lex_line(fstream_t fstream, context_t context,
-                 xbt_os_mutex_t mutex, const char *filepos, char *line) \r
-{
-  \rchar *line2;
-  \rvariable_t variable;
-  \runsigned int i;
-  \rchar exp[PATH_MAX + 1] = { 0 };
-  \runit_t unit = fstream->unit;
-  \rxbt_dynar_t variables = unit->runner->variables;
-  \rchar *p = NULL;
-  \rchar *end = NULL;
-  \rchar *val = NULL;
-  \rchar buff[PATH_MAX + 1] = { 0 };
-  \rsize_t len;
-  \rchar delimiters[4] = { ' ', '\t', '\n', '\0' };
-  \r\rint j;
-  \r\rif (line[0] == '#')
-    \rreturn;
-  \r\rif (unit->is_running_suite
-        && strncmp(line, "! include", strlen("! include")))
-    \r {                         /* it's the end of a suite */
-    \r\runit_t * current_suite =
-        xbt_dynar_get_ptr(unit->suites,
-                          xbt_dynar_length(unit->suites) - 1);
-    \r\rif (!xbt_dynar_length((*current_suite)->includes))
-      \rERROR2("[%s] Malformated suite `(%s)': include missing", filepos,
-              (*current_suite)->description);
-    \r
-    else
-      \rERROR2("[%s] Malformated suite `(%s)': blank line missing", filepos,
-              (*current_suite)->description);
-    \r\runit_set_error(*current_suite, ESYNTAX, 1, filepos);
-    \r\rfailure(fstream->unit);
-    \r}
-  \r\rcontext->line = strdup(filepos);
-  \r\r
-      /* search end */ \r
-      xbt_str_rtrim(line + 2, "\n");
-  \r\rline2 = strdup(line);
-  \r\rlen = strlen(line2 + 2) + 1;
-  \r\r
-      /* replace each variable by its value */ \r
-      xbt_os_mutex_acquire(unit->mutex);
-  \r\r\r
-      /* replace all existing\r
-         ${var}\r
-         ${var:=val}\r
-         ${var:+val}\r
-         ${var:-val}\r
-         ${var:?val}\r
-         ${#var}\r
-       */ \r
-      \rxbt_dynar_foreach(variables, i, variable) \r {
-    \rif (!(p = strstr(line2 + 2, "${")))
-      \rbreak;
-    \r\rmemset(buff, 0, len);
-    \r\rsprintf(buff, "${%s", variable->name);
-    \r\r
-        /* FALSE */ \r
-        if ((p = strstr(line2 + 2, buff)))
-      \r {
-      \rmemset(buff, 0, len);
-      \rp--;
-      \rj = 0;
-      \r\rwhile (*(p++) != '\0')
-        \r {
-        \rbuff[j++] = *p;
-        \r\rif (*p == '}')
-          \rbreak;
-        \r}
-      \r\rif (buff[j - 1] != '}')
-        \r {
-        \rxbt_os_mutex_release(unit->mutex);
-        \r\r\rERROR2("[%s] Syntax error : `%s'.", filepos, p - j);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rfailure(fstream->unit);
-        \rreturn;
-        \r}
-      \r\rif ((p = strstr(buff, ":=")))
-        \r {
-        \r
-            /* ${var:=val} */ \r
-            \r
-            /* if the value of the variable is empty, update its value by the value */ \r
-            p += 2;
-        \r\rend = strchr(p, '}');
-        \r\rif (!end || (end == p))
-          \r {
-          \rxbt_os_mutex_release(unit->mutex);
-          \r\r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                    strstr(buff, "${"));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \rreturn;
-          \r}
-        \r\rval = (char *) calloc((size_t) (end - p) + 1, sizeof(char));
-        \r\rstrncpy(val, p, (end - p));
-        \r\r\r
-            /* replace the expression by the expression of the value of the variable */ \r
-            sprintf(exp, "${%s:=%s}", variable->name, val);
-        \r\rif (variable->val)
-          \rstr_replace_all(&line2, exp, variable->val, NULL);
-        \r
-        else
-          \r {
-          \rstr_replace_all(&line2, exp, val, NULL);
-          \r\rvariable->val = strdup(val);
-          \r}
-        \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r\rif (val)
-          \r {
-          \rfree(val);
-          \rval = NULL;
-          \r}
-        \r\r}
-      \r
-      else if ((p = strstr(buff, ":-")))
-        \r {
-        \r
-            /* ${var:-val} */ \r
-            \r
-            /* if the value of the variable is empty, replace the expression by the value */ \r
-            p += 2;
-        \rend = strchr(p, '}');
-        \r\rif (!end || (end == p))
-          \r {
-          \rxbt_os_mutex_release(unit->mutex);
-          \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                   strstr(line2, "${"));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \rreturn;
-          \r}
-        \r\rval = (char *) calloc((size_t) (end - p) + 1, sizeof(char));
-        \r\rstrncpy(val, p, (end - p));
-        \r\rsprintf(exp, "${%s:-%s}", variable->name, val);
-        \r\rstr_replace_all(&line2, exp, variable->val ? variable->val : val,
-                          NULL);
-        \r\r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r\rif (val)
-          \r {
-          \rfree(val);
-          \rval = NULL;
-          \r}
-        \r\r}
-      \r
-      else if ((p = strstr(buff, ":+")))
-        \r {
-        \r
-            /* ${var:+val} */ \r
-            \r
-            /* if the value of the variable is not empty, replace the expression by the value */ \r
-            p += 2;
-        \r\rend = strchr(p, '}');
-        \r\rif (!end || (end == p))
-          \r {
-          \rxbt_os_mutex_release(unit->mutex);
-          \r\r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                    strstr(line2, "${"));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \rreturn;
-          \r}
-        \r\rval = (char *) calloc((size_t) (end - p) + 1, sizeof(char));
-        \r\rstrncpy(val, p, (end - p));
-        \r\rsprintf(exp, "${%s:+%s}", variable->name, val);
-        \r\rif (variable->val)
-          \r {
-          \rstr_replace_all(&line2, exp, val, NULL);
-          \r}
-        \r
-        else
-          \r {
-          \rstr_replace_all(&line2, exp, NULL, NULL);
-          \rvariable->val = strdup(val);
-          \r}
-        \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r\rif (val)
-          \r {
-          \rfree(val);
-          \rval = NULL;
-          \r}
-        \r}
-      \r
-      else if ((p = strstr(buff, ":?")))
-        \r {
-        \r
-            /*  ${var:?val} */ \r
-            \r
-            /* if the value of the variable is not empty, replace the expression by the value */ \r
-            p += 2;
-        \rend = strchr(p, '}');
-        \r\rif (!end || (end == p))
-          \r {
-          \rxbt_os_mutex_release(unit->mutex);
-          \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                   strstr(line2, "${"));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \rreturn;
-          \r}
-        \r\rval = (char *) calloc((size_t) (end - p) + 1, sizeof(char));
-        \r\rstrncpy(val, p, (end - p));
-        \r\rsprintf(exp, "${%s:?%s}", variable->name, val);
-        \r\rif (variable->val)
-          \rstr_replace_all(&line2, exp, variable->val, NULL);
-        \r
-        else
-          \r {
-          \r\rxbt_os_mutex_release(unit->mutex);
-          \r\rERROR2("[%s] %s.", filepos, val);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \rreturn;
-          \r}
-        \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r\rif (val)
-          \r {
-          \rfree(val);
-          \rval = NULL;
-          \r}
-        \r}
-      \r}
-  \r}
-  \r\r
-      /* replace all existing $var */ \r
-      xbt_dynar_foreach(variables, i, variable) \r {
-    \rif (!strchr(line2 + 2, '$'))
-      \rbreak;
-    \r\rif (strstr(line2 + 2, variable->name))
-      \r {
-      \r\rsprintf(exp, "${#%s}", variable->name);
-      \r\rif (strstr(line2 + 2, exp))
-        \r {
-        \r\rif (variable->val)
-          \r {
-          \rchar slen[4] = { 0 };
-          \rsprintf(slen, "%d", (int) strlen(variable->val));
-          \rstr_replace_all(&line2, exp, slen, NULL);
-          \r}
-        \r
-        else
-          \rstr_replace_all(&line2, exp, "0", NULL);
-        \r}
-      \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-      \r\rsprintf(exp, "${%s}", variable->name);
-      \r\rif (strstr(line2 + 2, exp))
-        \r {
-        \rif (variable->val)
-          \rstr_replace_all(&line2, exp, variable->val, NULL);
-        \r
-        else
-          \rstr_replace_all(&line2, exp, NULL, NULL);
-        \r}
-      \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-      \r\rsprintf(exp, "$%s", variable->name);
-      \r\rif ((p = strstr(line2 + 2, exp)))
-        \r {
-        \rif ((p + strlen(variable->name) + 1)[0] != '\0'
-             && !(isalpha((p + strlen(variable->name) + 1)[0])))
-          \rdelimiters[0] = (p + strlen(variable->name) + 1)[0];
-        \r\rif (variable->val)
-          \rstr_replace_all(&line2, exp, variable->val, delimiters);
-        \r
-        else
-          \rstr_replace_all(&line2, exp, NULL, delimiters);
-        \r}
-      \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-      \r\r}
-  \r}
-  \r\rwhile ((p = strstr(line2 + 2, "${")))
-    \r {
-    \r
-        /*if(*(p+1) != '{')\r
-           {\r
-           j = 0;\r
-           p --;\r
-           \r
-           while(*(p++) != '\0')\r
-           {\r
-           if(*p != ' ' && *p !='\t')\r
-           exp[j++] = *p;\r
-           else\r
-           break;\r
-           \r
-           }\r
-           \r
-           str_replace_all(&line2, exp, NULL, " \t\n\r");\r
-           memset(exp, 0, VAR_NAME_MAX + 1);\r
-           }.\r
-           else\r
-         */ \r
-    {
-      \rchar *begin = NULL;
-      \r\rj = 0;
-      \rp--;
-      \r\rwhile (*(p++) != '\0')
-        \r {
-        \rif ((!begin && *p != ' ' && *p != '\t') || begin)
-          \r {
-          \r
-              /* `:' must be before this caracter, bad substitution : exit loop \r
-                 ||\r
-                 the current character is already present, bad substitution : exit loop\r
-               */ \r
-              if (\r
-                  (\r*(p - 1) != ':' && (\r
-                                        (*p == '=') || (*p == '-')
-                                        || (*p == '+')
-                                        || (*p == '?') \r\r\r ||\r(\rbegin
-                                                                   &&
-                                                                   (\r
-                                                                    (*p ==
-                                                                     ':')
-                                                                    || (*p
-                                                                        ==
-                                                                        '=')
-                                                                    || (*p
-                                                                        ==
-                                                                        '-')
-                                                                    || (*p
-                                                                        ==
-                                                                        '+')
-                                                                    || (*p
-                                                                        ==
-                                                                        '?')
-                                                                    \r\r)
-                  \r)
-            \rbreak;
-          \r
-          else
-            \rexp[j++] = *p;
-          \r\rif (*p == ':')
-            \r {
-            \r
-                /* save the begining of the value */ \r
-                if ((*(p + 1) == '=') || (*(p + 1) == '-')
-                    || (*(p + 1) == '+') || (*(p + 1) == '?'))
-              \r {
-              \rbegin = p + 2;
-              \rexp[j++] = *(p + 1);
-              \rp++;
-              \rcontinue;
-              \r\r}
-            \r
-            else
-              \r
-                  /* the current char is `:' but the next is invalid, bad substitution : exit loop */ \r
-                  break;
-            \r}
-          \r
-              /* end of the substitution : exit loop */ \r
-              else if (*p == '}')
-            \rbreak;
-          \r}
-        \r
-        else
-          \rbreak;
-        \r}
-      \r\rif (exp[j - 1] == '}')
-        \r {
-        \rif (exp[2] == '#')
-          \r {
-          \r
-              /* ${#var} */ \r
-              \r\rif (4 == strlen(exp))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                     strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rstr_replace_all(&line2, exp, "0", NULL);
-          \r}
-        \r
-        else if (strstr(exp, ":="))
-          \r {
-          \r
-              /* ${var:=value} */ \r
-              \rend = strchr(p, '}');
-          \r\rif (!end || (end == begin))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                      strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rvariable = xbt_new0(s_variable_t, 1);
-          \r\rvariable->val =
-              (char *) calloc((size_t) (end - begin) + 1, sizeof(char));
-          \r\rstrncpy(variable->val, begin, (end - begin));
-          \r\rbegin = exp + 2;
-          \rend = strchr(exp, ':');
-          \r\rif (!end || (end == begin))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                      strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rvariable->name =
-              (char *) calloc((size_t) (end - begin) + 1, sizeof(char));
-          \r\rstrncpy(variable->name, exp + 2, (end - begin));
-          \r\rstr_replace_all(&line2, exp, variable->val, NULL);
-          \r\rxbt_dynar_push(variables, &variable);
-          \r\r}
-        \r
-        else if (strstr(exp, ":-"))
-          \r {
-          \r
-              /* ${var:-value} */ \r
-              \r\rend = strchr(p, '}');
-          \r\rif (!end || (end == begin))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                      strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rval =
-              (char *) calloc((size_t) (end - begin) + 1, sizeof(char));
-          \r\rstrncpy(val, begin, (end - begin));
-          \r\rstr_replace_all(&line2, exp, val, NULL);
-          \r\rif (val)
-            \rfree(val);
-          \r\r}
-        \r
-        else if (strstr(exp, ":+"))
-          \r {
-          \r
-              /* ${var:+value} */ \r
-              \rend = strchr(p, '}');
-          \r\rif (!end || (end == begin))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                     strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rstr_replace_all(&line2, exp, NULL, NULL);
-          \r}
-        \r
-        else if (strstr(exp, ":?"))
-          \r {
-          \r
-              /* ${var:?value} */ \r
-              \rend = strchr(p, '}');
-          \r\rif (!end || (end == begin))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                     strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rval =
-              (char *) calloc((size_t) (end - begin) + 1, sizeof(char));
-          \r\rstrncpy(val, begin, (end - begin));
-          \r\rxbt_os_mutex_release(unit->mutex);
-          \r\rERROR2("[%s] : `%s'.", filepos, val);
-          \r\rif (val)
-            \rfree(val);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(fstream->unit);
-          \r\rreturn;
-          \r\r}
-        \r
-        else
-          \r {
-          \r
-              /* ${var} */ \r
-              \rif (3 == strlen(exp))
-            \r {
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                     strchr(line2 + 2, '$'));
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(fstream->unit);
-            \rreturn;
-            \r}
-          \r\rstr_replace_all(&line2, exp, NULL, NULL);
-          \r\r}
-        \r\rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r}
-      \r
-      else
-        \r {
-        \rxbt_os_mutex_release(unit->mutex);
-        \r\rif (strstr(line2 + 2, "${"))
-          \rERROR2("[%s] Bad substitution : `%s'.", filepos,
-                  strstr(line2, "${"));
-        \r
-        else
-          \rERROR2("[%s] Syntax error : `%s'.", filepos,
-                  strstr(line2, "${"));
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rfailure(fstream->unit);
-        \rreturn;
-        \r}
-    \r\r}
-    \r\r}
-  \r\rwhile (1)
-    \r {
-    \rp = line2 + (line2[0] == '<' ? 4 : 2);
-    \r\rif ((p = strchr(p, '$')))
-      \r {
-      \rif (*(p + 1) != ' ')
-        \r {
-        \rj = 0;
-        \rp--;
-        \r\rwhile (*(p++) != '\0')
-          \r {
-          \rif (*p != ' ' && *p != '\t')
-            \rexp[j++] = *p;
-          \r
-          else
-            \rbreak;
-          \r\r}
-        \r\rstr_replace_all(&line2, exp, NULL, " \t\n\r");
-        \rmemset(exp, 0, VAR_NAME_MAX + 1);
-        \r}
-      \r
-      else
-        \r {
-        \r
-            /* maybe < $ cmd */ \r
-            p++;
-        \r}
-      \r}
-    \r
-    else
-      \rbreak;
-    \r}
-  \r\rxbt_os_mutex_release(unit->mutex);
-  \r\rswitch (line2[0])
-    \r {
-    \r
-        /*case '#': \r
-           break;\r
-         */ \r
-  \rcase '$':
-  \rcase '&':
-    \r\rif (line[1] != ' ')
-      \r {
-      \r\rif (line2[0] == '$')
-        \rERROR1("[%s] Missing space after `$' `(usage : $ <command>)'",
-                filepos);
-      \r
-      else
-        \rERROR1("[%s] Missing space after & `(usage : & <command>)'",
-                filepos);
-      \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-      \r\rfailure(unit);
-      \rreturn;
-      \r}
-    \r\rcontext->async = (line2[0] == '&');
-    \r\r\r
-        /* further trim useless chars which are significant for in/output */ \r
-        xbt_str_rtrim(line2 + 2, " \t");
-    \r\r
-        /* deal with CD commands here, not in context */ \r
-        if (!strncmp("cd ", line2 + 2, 3))
-      \r {
-      \rchar *dir = strdup(line2 + 4);
-      \r\rif (context->command_line)
-        \r {
-        \rif (fstream_launch_command(fstream, context, mutex) < 0)
-          \rreturn;
-        \r}
-      \r\r
-          /* search begining */ \r
-          while (*(dir++) == ' ');
-      \r\rdir--;
-      \r\rif (!dry_run_flag)
-        \r {
-        \rif (!silent_flag)
-          \rINFO2("[%s] cd %s", filepos, dir);
-        \r\rif (!just_print_flag)
-          \r {
-          \rif (chdir(dir))
-            \r {
-            \rERROR3("[%s] Chdir to %s failed: %s", filepos, dir,
-                    error_to_string(errno, 0));
-            \runit_set_error(fstream->unit, errno, 0, filepos);
-            \r\rfailure(unit);
-            \r}
-          \r}
-        \r}
-      \r\rbreak;
-      \r}
-    \r
-    else
-      \r {
-      \rfstream_process_token(fstream, context, mutex, filepos, line2[0],
-                             line2 + 2);
-      \rbreak;
-      \r}
-  \r\rcase '<':
-  \rcase '>':
-  \rcase '!':
-    \r\rif (line[0] == '!' && line[1] != ' ')
-      \r {
-      \rERROR1
-          ("[%s] Missing space after `!' `(usage : ! <command> [[=]value])'",
-           filepos);
-      \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-      \r\rfailure(unit);
-      \rreturn;
-      \r}
-    \r\rfstream_process_token(fstream, context, mutex, filepos, line2[0],
-                            line2 + 2);
-    \rbreak;
-  \r\rcase 'p':
-    \r\r {
-      \runsigned int j;
-      \rint is_blank = 1;
-      \r\rchar *prompt = line2 + 2;
-      \r\rfor (j = 0; j < strlen(prompt); j++)
-        \r {
-        \rif (prompt[j] != ' ' && prompt[j] != '\t')
-          \r {
-          \ris_blank = 0;
-          \rbreak;
-          \r}
-        \r}
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand p `(usage : p <prompt>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rif (!dry_run_flag)
-        \rINFO2("[%s] %s", filepos, prompt);
-    \r}
-    \r\r\rbreak;
-  \r\rcase 'P':
-    \r\r {
-      \runsigned int j;
-      \rint is_blank = 1;
-      \r\rchar *prompt = line2 + 2;
-      \r\rfor (j = 0; j < strlen(prompt); j++)
-        \rif (prompt[j] != ' ' && prompt[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand P `(usage : P <prompt>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rif (!dry_run_flag)
-        \rCRITICAL2("[%s] %s", filepos, prompt);
-    \r}
-    \r\rbreak;
-  \r\rcase 'D':
-    \rif (unit->description)
-      \rWARN2("[%s] Description already specified `%s'", filepos,
-             line2 + 2);
-    \r
-    else
-      \r {
-      \runsigned int j;
-      \rint is_blank = 1;
-      \r\rchar *desc = line2 + 2;
-      \r\rfor (j = 0; j < strlen(desc); j++)
-        \rif (desc[j] != ' ' && desc[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand D `(usage : D <Description>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\runit->description = strdup(desc);
-      \r}
-    \rbreak;
-  \r\rdefault:
-    \rERROR2("[%s] Syntax error `%s'", filepos, line2);
-    \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-    \rfailure(unit);
-    \rbreak;
-    \r}
-  \r\rfree(line2);
-\r}
-
-\r\rvoid \r
-fstream_process_token(fstream_t fstream, context_t context,
-                      xbt_os_mutex_t mutex, const char *filepos,
-                      char token, char *line) \r
-{
-  \runit_t unit = fstream->unit;
-  \r\rswitch (token)
-    \r {
-  \rcase '$':
-  \rcase '&':
-    \r\rif (context->command_line)
-      \r {
-      \r\rif (context->output->used || context->input->used)
-        \r {
-        \rERROR2
-            ("[%s] More than one command in this chunk of lines (previous: %s).\nDunno which input/output belongs to which command.",
-             filepos, context->command_line);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rif (fstream_launch_command(fstream, context, mutex) < 0)
-        \rreturn;
-      \r\rVERB1("[%s] More than one command in this chunk of lines",
-              filepos);
-      \r}
-    \r\r {
-      \rsize_t j, \ris_blank = 1;
-      \r\rfor (j = 0; j < strlen(line); j++)
-        \rif (line[j] != ' ' && line[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rif (token == '$')
-          \rERROR1("[%s] Undefinite command for `$' `(usage: $ <command>)'",
-                  filepos);
-        \r
-        else
-          \rERROR1("[%s] Undefinite command for `&' `(usage: & <command>)'",
-                  filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-    \r}
-    \r\rcontext->command_line = strdup(line);
-    \r\rxbt_str_ltrim(context->command_line, " ");
-    \r\rcontext->line = /*strdup(filepos) */ filepos;
-    \rcontext->pos = strdup(filepos);
-    \r\r
-#ifdef _XBT_WIN32\r
-    {
-      \r\r
-          /* translate the command line */ \r
-      \rchar *path = NULL;
-      \rchar *delimiter;
-      \rchar command_line[PATH_MAX + 1] = { 0 };
-      \rsize_t i = 0;
-      \rchar *args = NULL;
-      \r\r\r\r
-          /*if(strstr(context->command_line,".exe"))\r
-             strcpy(command_line,context->command_line); */ \r
-          \r {
-        \rsize_t len;
-        \r\rsize_t j = 0;
-        \r\rlen = strlen(context->command_line);
-        \r\rwhile (i < len)
-          \r {
-          \rif (context->command_line[i] != ' '
-               && context->command_line[i] != '\t'
-               && context->command_line[i] != '>')
-            \rcommand_line[j++] = context->command_line[i];
-          \r
-          else
-            \rbreak;
-          \r\ri++;
-          \r}
-        \r\rif (!strstr(context->command_line, ".exe"))
-          \rstrcat(command_line, ".exe");
-        \r\rargs = strdup(context->command_line + i);
-      \r}
-      \r\rif (!is_w32_cmd(command_line, fstream->unit->runner->path)
-            && getpath(command_line, &path) < 0)
-        \r {
-        \rcommand_t command;
-        \r\rERROR3("[%s] `%s' : NOK (%s)", filepos, command_line,
-                 error_to_string(ECMDNOTFOUND, 1));
-        \runit_set_error(fstream->unit, ECMDNOTFOUND, 1, filepos);
-        \r\rcontext->is_not_found = 1;
-        \r\rcommand = command_new(fstream->unit, context, mutex);
-        \r\rcommand->status = cs_failed;
-        \rcommand->reason = csr_command_not_found;
-        \r\rfailure(unit);
-        \r\r\rreturn;
-        \r}
-      \r\rdelimiter = strrchr(command_line, '/');
-      \r\rif (!delimiter)
-        \rdelimiter = strrchr(command_line, '\\');
-      \r\r
-          /*free(context->command_line); */ \r
-          \r\rif (path)
-        \r {
-        \rif (args)
-          \r {
-          \rcontext->t_command_line =
-              (char *) calloc(strlen(path) +
-                              strlen(delimiter ? delimiter +
-                                     1 : command_line) + strlen(args) + 2,
-                              sizeof(char));
-          \rsprintf(context->t_command_line, "%s\\%s%s", path,
-                   delimiter ? delimiter + 1 : command_line, args);
-          \r\rfree(args);
-          \r\r}
-        \r
-        else
-          \r {
-          \rcontext->t_command_line =
-              (char *) calloc(strlen(path) +
-                              strlen(delimiter ? delimiter +
-                                     1 : command_line) + 2, sizeof(char));
-          \rsprintf(context->t_command_line, "%s\\%s", path,
-                   delimiter ? delimiter + 1 : command_line);
-          \r\r\rfree(path);
-        \r}
-      \r
-      else
-        \r {
-        \rif (args)
-          \r {
-          \r\rcontext->t_command_line =
-              (char *) calloc(strlen(command_line) + strlen(args) + 1,
-                              sizeof(char));
-          \rsprintf(context->t_command_line, "%s%s", command_line, args);
-          \r\r\rfree(args);
-          \r\r}
-        \r
-        else
-          \r {
-          \rcontext->t_command_line =
-              (char *) calloc(strlen(command_line) + 1, sizeof(char));
-          \rstrcpy(context->t_command_line, command_line);
-    \r\r\r\r\r\r
-#endif  /* \r */
-        \r\rbreak;
-  \r\rcase '<':
-    \rxbt_strbuff_append(context->input, line);
-    \rxbt_strbuff_append(context->input, "\n");
-    \rbreak;
-  \r\rcase '>':
-    \rxbt_strbuff_append(context->output, line);
-    \rxbt_strbuff_append(context->output, "\n");
-    \rbreak;
-  \r\rcase '!':
-    \r\rif (context->command_line)
-      \r {
-      \rif (fstream_launch_command(fstream, context, mutex) < 0)
-        \rreturn;
-      \r}
-    \r\rif (!strncmp(line, "timeout no", strlen("timeout no")))
-      \r {
-      \rVERB1("[%s] (disable timeout)", filepos);
-      \rcontext->timeout = INDEFINITE;
-      \r}
-    \r
-    else if (!strncmp(line, "timeout ", strlen("timeout ")))
-      \r {
-      \rint i = 0;
-      \runsigned int j;
-      \rint is_blank = 1;
-      \rchar *p = line + strlen("timeout ");
-      \r\r\rfor (j = 0; j < strlen(p); j++)
-        \rif (p[j] != ' ' && p[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Undefinite timeout value `(usage :timeout <seconds>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rwhile (p[i] != '\0')
-        \r {
-        \rif (!isdigit(p[i]))
-          \r {
-          \rERROR2
-              ("[%s] Invalid timeout value `(%s)' : `(usage :timeout <seconds>)'",
-               filepos, line + strlen("timeout "));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\ri++;
-        \r}
-      \r\rcontext->timeout = atoi(line + strlen("timeout"));
-      \rVERB2("[%s] (new timeout value: %d)", filepos, context->timeout);
-      \r\r}
-    \r
-    else if (!strncmp(line, "expect signal ", strlen("expect signal ")))
-      \r {
-      \runsigned int j;
-      \rint is_blank = 1;
-      \r\r\rchar *p = line + strlen("expect signal ");
-      \r\r\rfor (j = 0; j < strlen(p); j++)
-        \rif (p[j] != ' ' && p[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Undefinite signal name `(usage :expect signal <signal name>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rcontext->signal = strdup(line + strlen("expect signal "));
-      \r\rxbt_str_trim(context->signal, " \n");
-      \r\r
-#ifdef _XBT_WIN32\r
-          if (!strstr("SIGSEGVSIGTRAPSIGBUSSIGFPESIGILL", context->signal))
-        \r {
-        \rERROR2("[%s] Signal `%s' not supported by this platform", filepos,
-                context->signal);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r
-#else   /* \r */
-          if (!sig_exists(context->signal))
-        \r {
-        \rERROR2("[%s] Signal `%s' not supported by Tesh", filepos,
-                context->signal);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\r
-#endif  /* \r */
-          \r\rVERB2("[%s] (next command must raise signal %s)", filepos,
-                  context->signal);
-      \r\r}
-    \r
-    else if (!strncmp(line, "expect return ", strlen("expect return ")))
-      \r {
-      \r\rint i = 0;
-      \runsigned int j;
-      \rint is_blank = 1;
-      \rchar *p = line + strlen("expect return ");
-      \r\r\rfor (j = 0; j < strlen(p); j++)
-        \rif (p[j] != ' ' && p[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Undefinite return value `(usage :expect return <return value>)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rwhile (p[i] != '\0')
-        \r {
-        \rif (!isdigit(p[i]))
-          \r {
-          \rERROR2
-              ("[%s] Invalid exit code value `(%s)' : must be an integer >= 0 and <=255",
-               filepos, line + strlen("expect return "));
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\ri++;
-        \r}
-      \r\rcontext->exit_code = atoi(line + strlen("expect return "));
-      \rVERB2("[%s] (next command must return code %d)", filepos,
-             context->exit_code);
-      \r\r}
-    \r
-    else if (!strncmp(line, "output ignore", strlen("output ignore")))
-      \r {
-      \rcontext->output_handling = oh_ignore;
-      \rVERB1("[%s] (ignore output of next command)", filepos);
-      \r\r}
-    \r
-    else if (!strncmp(line, "output display", strlen("output display")))
-      \r {
-      \rcontext->output_handling = oh_display;
-      \rVERB1("[%s] (ignore output of next command)", filepos);
-      \r\r}
-    \r
-    else if (!strncmp(line, "include ", strlen("include ")))
-      \r {
-      \rchar *p1;
-      \rchar *p2;
-      \r\rp1 = line + strlen("include");
-      \r\rwhile (*p1 == ' ' || *p1 == '\t')
-        \rp1++;
-      \r\r\rif (p1[0] == '\0')
-        \r {
-        \rERROR1
-            ("[%s] no file specified : `(usage : include <file> [<description>])'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r
-      else
-        \r {
-        \rchar file_name[PATH_MAX + 1] = { 0 };
-        \r\rp2 = p1;
-        \r\rwhile (*p2 != '\0' && *p2 != ' ' && *p2 != '\t')
-          \rp2++;
-        \r\rstrncpy(file_name, p1, p2 - p1);
-        \r\r\rif (p2[0] != '\0')
-          \rwhile (*p2 == ' ' || *p2 == '\t')
-            \rp2++;
-        \r\rfstream_handle_include(fstream, context, mutex, file_name,
-                                 p2[0] != '\0' ? p2 : NULL);
-        \r\r}
-      \r}
-    \r
-    else if (!strncmp(line, "suite ", strlen("suite ")))
-      \r {
-      \runsigned int j;
-      \rint is_blank = 1;
-      \rchar *p = line + strlen("suite ");
-      \r\r\rfor (j = 0; j < strlen(p); j++)
-        \rif (p[j] != ' ' && p[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Undefinite suit description : `(usage : suite <description>)",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rif (unit->is_running_suite)
-        \r {
-        \rERROR1("[%s] Suite already in progress", filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rfstream_handle_suite(fstream, line + strlen("suite "), filepos);
-      \r}
-    \r
-    else if (!strncmp(line, "unsetenv ", strlen("unsetenv ")))
-      \r {
-      \runsigned int i, j;
-      \rint exists = 0;
-      \rint env = 0;
-      \rint err = 0;
-      \rvariable_t variable;
-      \rint is_blank;
-      \r\rchar *name = line + strlen("unsetenv ");
-      \r\ris_blank = 1;
-      \r\rfor (j = 0; j < strlen(name); j++)
-        \rif (name[j] != ' ' && name[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand unsetenv : `(usage : unsetenv variable)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rxbt_os_mutex_acquire(unit->mutex);
-      \r\r\rxbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-        \rif (!strcmp(variable->name, name))
-          \r {
-          \renv = variable->env;
-          \rerr = variable->err;
-          \rexists = 1;
-          \rbreak;
-          \r}
-      \r}
-      \r\rif (env)
-        \r {
-        \rif (exists)
-          \r {
-          \r
-#ifndef _XBT_WIN32\r
-              unsetenv(name);
-          \r
-#else   /* \r */
-              SetEnvironmentVariable(name, NULL);
-          \r
-#endif  /* \r */
-              xbt_dynar_cursor_rm(unit->runner->variables, &i);
-          \r}
-        \r
-        else
-          \r {
-          \rERROR2
-              ("[%s] `(%s)' environment variable not found : impossible to unset it",
-               filepos, name);
-          \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rxbt_os_mutex_release(unit->mutex);
-          \rfailure(unit);
-          \rreturn;
-          \r}
-        \r}
-      \r
-      else
-        \r {
-        \rif (exists)
-          \r {
-          \rif (!err)
-            \r {
-            \rERROR2
-                ("[%s] `(%s)' is not an environment variable : use `unset' instead `unsetenv'",
-                 filepos, name);
-            \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rfailure(unit);
-            \rxbt_os_mutex_release(unit->mutex);
-            \rreturn;
-            \r}
-          \r
-          else
-            \r {
-            \rERROR2
-                ("[%s] `(%s)' is not an environment variable (it's a system variable) : impossible to unset it",
-                 filepos, name);
-            \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \rfailure(unit);
-            \rreturn;
-            \r}
-          \r}
-        \r
-        else
-          \r {
-          \rERROR2
-              ("[%s] `(%s)' environment variable not found : impossible to unset it",
-               filepos, name);
-          \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rxbt_os_mutex_release(unit->mutex);
-          \rfailure(unit);
-          \rreturn;
-          \r}
-        \r}
-      \r\rxbt_os_mutex_release(unit->mutex);
-      \r\r\r}
-    \r
-    else if (!strncmp(line, "setenv ", strlen("setenv ")))
-      \r {
-      \rchar *val;
-      \rchar name[PATH_MAX + 1] = { 0 };
-      \rchar *p;
-      \runsigned int i;
-      \rint is_blank;
-      \runsigned int j;
-      \r\rp = line + strlen("setenv ");
-      \r\rval = strchr(p, '=');
-      \r\rif (val)
-        \r {
-        \rvariable_t variable;
-        \rint exists = 0;
-        \rint env = 0;
-        \rint err = 0;
-        \rval++;
-        \r\r
-            /* syntax error */ \r
-            if (val[0] == '\0' || val[0] == ' ' || val[0] == '\t')
-          \r {
-          \rERROR1
-              ("[%s] Bad usage of the metacommand setenv `(usage : setenv variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\r\r\rstrncpy(name, p, (val - p - 1));
-        \r\ris_blank = 1;
-        \r\rfor (j = 0; j < strlen(name); j++)
-          \rif (name[j] != ' ' && name[j] != '\t')
-            \ris_blank = 0;
-        \r\rif (is_blank)
-          \r {
-          \r\rERROR1
-              ("[%s] Bad usage of the metacommand setenv `(usage : setenv variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\r
-            /* test if the variable is already registred */ \r
-            xbt_os_mutex_acquire(unit->mutex);
-        \r\rxbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-          \rif (!strcmp(variable->name, name))
-            \r {
-            \renv = variable->env;
-            \rerr = variable->err;
-            \rexists = 1;
-            \rbreak;
-            \r}
-        \r}
-        \r\r
-            /* if the variable is already registred, update its value;\r
-             * otherwise register it.\r
-             */ \r
-            if (exists)
-          \r {
-          \rif (env)
-            \r {
-            \rif (!strcmp(val, variable->val))
-              \rWARN3
-                  ("[%s] This environment variable `(%s)' is already set with the value `(%s)'",
-                   filepos, name, val);
-            \r\rfree(variable->val);
-            \rvariable->val = strdup(val);
-            \r\r
-#ifdef _XBT_WIN32\r
-                SetEnvironmentVariable(variable->name, variable->val);
-            \r
-#else   /* \r */
-                setenv(variable->name, variable->val, 1);
-            \r
-#endif  /* \r */
-            }
-          \r
-          else
-            \r {
-            \rif (err)
-              \rERROR2
-                  ("[%s] Conflict : a system variable `(%s)' already exists",
-                   filepos, name);
-            \r
-            else
-              \rERROR2
-                  ("[%s] Conflict : (none environment) variable `(%s)' already exists",
-                   filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \rfailure(unit);
-            \rreturn;
-            \r}
-          \r}
-        \r
-        else
-          \r {
-          \rif (err)
-            \r {
-            \rERROR2("[%s] A system variable named `(%s)' already exists",
-                    filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \rfailure(unit);
-            \rreturn;
-            \r}
-          \r
-          else
-            \r {
-            \rvariable = variable_new(name, val);
-            \rvariable->env = 1;
-            \r\rxbt_dynar_push(unit->runner->variables, &variable);
-            \r\r
-#ifdef _XBT_WIN32\r
-                SetEnvironmentVariable(variable->name, variable->val);
-            \r
-#else   /* \r */
-                setenv(variable->name, variable->val, 0);
-            \r
-#endif  /* \r */
-            }
-          \r}
-        \r\rxbt_os_mutex_release(unit->mutex);
-        \r\r}
-      \r
-      else
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand setenv `(usage : setenv variable=value)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rfailure(unit);
-        \rreturn;
-        \r}
-      \r}
-    \r
-    else if (!strncmp(line, "unset ", strlen("unset ")))
-      \r {
-      \runsigned int i, j;
-      \rint exists = 0;
-      \rint env = 0;
-      \rint err = 0;
-      \rvariable_t variable;
-      \rint is_blank;
-      \r\rchar *name = line + strlen("unset ");
-      \r\ris_blank = 1;
-      \r\rfor (j = 0; j < strlen(name); j++)
-        \rif (name[j] != ' ' && name[j] != '\t')
-          \ris_blank = 0;
-      \r\rif (is_blank)
-        \r {
-        \r\rERROR1
-            ("[%s] Bad usage of the metacommand unset `(usage : unset variable)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r\r\rxbt_os_mutex_acquire(unit->mutex);
-      \r\rxbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-        \rif (!strcmp(variable->name, name))
-          \r {
-          \renv = variable->env;
-          \rerr = variable->err;
-          \rexists = 1;
-          \rbreak;
-          \r}
-      \r}
-      \r\rif (!env && !err)
-        \r {
-        \rif (exists)
-          \r {
-          \r
-              /*xbt_dynar_remove_at(unit->runner->variables, i, NULL); */ \r
-              /*xbt_dynar_cursor_rm(unit->runner->variables, &i); */ \r
-              if (variable->val)
-            \r {
-            \rfree(variable->val);
-            \rvariable->val = NULL;
-            \r}
-          \r
-          else
-            \r {
-            \rWARN2("[%s] Variable `(%s)' already unseted", filepos,
-                   variable->name);
-            \r}
-          \r}
-        \r
-        else
-          \r {
-          \rERROR2("[%s] `(%s)' variable not found", filepos, name);
-          \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rxbt_os_mutex_release(unit->mutex);
-          \rfailure(unit);
-          \rreturn;
-          \r}
-        \r}
-      \r
-      else if (env)
-        \r {
-        \rERROR2
-            ("[%s] `(%s)' is an environment variable use `unsetenv' instead `unset'",
-             filepos, name);
-        \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rxbt_os_mutex_release(unit->mutex);
-        \rfailure(unit);
-        \rreturn;
-        \r}
-      \r
-      else if (err)
-        \r {
-        \rERROR2("[%s] `(%s)' is system variable : you can unset it",
-                filepos, name);
-        \runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rxbt_os_mutex_release(unit->mutex);
-        \rfailure(unit);
-        \rreturn;
-        \r}
-      \r\rxbt_os_mutex_release(unit->mutex);
-      \r\r}
-    \r
-    else if (!strncmp(line, "set ", strlen("set ")))
-      \r {
-      \rchar *val;
-      \rchar name[PATH_MAX + 1] = { 0 };
-      \runsigned int j;
-      \rint is_blank;
-      \r\rval = strchr(line + strlen("set "), '=');
-      \r\rif (val)
-        \r {
-        \rvariable_t variable;
-        \rint exists = 0;
-        \runsigned int i;
-        \rint err;
-        \rint env;
-        \r\rval++;
-        \r\r\r
-            /* syntax error */ \r
-            if (val[0] == '\0')
-          \r {
-          \rERROR1
-              ("[%s] Bad usage of the metacommand set `(usage : set variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r
-        else if (val[0] == ' ' || val[0] == '\t')
-          \r {
-          \rstrncpy(name, line + strlen("set "),
-                   (val - (line + strlen("set "))));
-          \r\rERROR2("[%s] No space avaible after`(%s)'", filepos, name);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\r\r
-            /* assume it's a varibale */ \r
-            \rstrncpy(name, line + strlen("set "),
-                     (val - (line + strlen("set ")) - 1));
-        \r\ris_blank = 1;
-        \r\rfor (j = 0; j < strlen(name); j++)
-          \rif (name[j] != ' ' && name[j] != '\t')
-            \ris_blank = 0;
-        \r\rif (is_blank)
-          \r {
-          \r\rERROR1
-              ("[%s] Bad usage of the metacommand set `(usage : set variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\rxbt_os_mutex_acquire(unit->mutex);
-        \r\r
-            /* test if the variable is already registred */ \r
-            xbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-          \rif (!strcmp(variable->name, name))
-            \r {
-            \rexists = 1;
-            \rerr = variable->err;
-            \renv = variable->env;
-            \rbreak;
-            \r}
-        \r}
-        \r\r
-            /* if the variable is already registred, update its value (if same value warns);\r
-             * otherwise register it.\r
-             */ \r
-            if (exists)
-          \r {
-          \rif (err)
-            \r {
-            \rERROR2("[%s] A system variable named `(%s)' already exists",
-                    filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rfailure(unit);
-            \rreturn;
-            \r}
-          \rif (env)
-            \r {
-            \rERROR2
-                ("[%s] `(%s)' is an environment variable use `setenv' instead `set'",
-                 filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rfailure(unit);
-            \rreturn;
-            \r}
-          \r
-          else
-            \r {
-            \rif (!strcmp(val, variable->val))
-              \rWARN3("[%s] Variable `(%s)' already contains value `<%s>'",
-                     filepos, variable->name, val);
-            \r\rfree(variable->val);
-            \rvariable->val = strdup(val);
-            \r}
-          \r}
-        \r
-        else
-          \r {
-          \rvariable_t new_var = variable_new(name, val);
-          \rxbt_dynar_push(unit->runner->variables, &new_var);
-          \r}
-        \r\r\rxbt_os_mutex_release(unit->mutex);
-        \r}
-      \r
-      else
-        \r {
-        \rERROR1
-            ("[%s] Bad usage of the metacommand set `(usage : set variable=value)'",
-             filepos);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \rfailure(unit);
-        \rreturn;
-        \r}
-      \r}
-    \r
-    else
-      \r {                       /* assume it's a variable */
-      \rchar *val;
-      \rchar name[PATH_MAX + 1] = { 0 };
-      \runsigned int i, j;
-      \rint is_blank;
-      \r\rval = strchr(line, '=');
-      \r\rif (val)
-        \r {
-        \rvariable_t variable;
-        \rint exists = 0;
-        \rint err;
-        \rint env;
-        \rval++;
-        \r\r\r
-            /* syntax error */ \r
-            if (val[0] == '\0')
-          \r {
-          \rstrncpy(name, line, (val - line - 1));
-          \r\ris_blank = 1;
-          \r\rfor (j = 0; j < strlen(name); j++)
-            \rif (name[j] != ' ' && name[j] != '\t')
-              \ris_blank = 0;
-          \r\rif (is_blank)
-            \rERROR1
-                ("[%s] Bad usage of Tesh variable mechanism `(usage : variable=value)'",
-                 filepos);
-          \r
-          else if (!strcmp("setenv", name))
-            \rERROR1
-                ("[%s] Bad usage of the metacommand setenv `(usage : setenv variable=value)'",
-                 filepos);
-          \r
-          else if (!strcmp("set", name))
-            \rERROR1
-                ("[%s] Bad usage of the metacommand set `(usage : set variable=value)'",
-                 filepos);
-          \r
-          else
-            \rERROR2("[%s] Undefined variable `(%s)'", filepos, name);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r
-        else if (val[0] == ' ' || val[0] == '\t')
-          \r {
-          \rstrncpy(name, line, (val - line));
-          \r\rERROR2("[%s] No space avaible after`(%s)'", filepos, name);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \r}
-        \r\r\r
-            /* assume it's a varibale */ \r
-            \rstrncpy(name, line, (val - line - 1));
-        \r\ris_blank = 1;
-        \r\rfor (j = 0; j < strlen(name); j++)
-          \rif (name[j] != ' ' && name[j] != '\t')
-            \ris_blank = 0;
-        \r\rif (is_blank)
-          \r {
-          \r\rERROR1
-              ("[%s] Bad usage of Tesh variable capability `(usage : variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \r\rfailure(unit);
-          \rreturn;
-          \r}
-        \r\rif (!strcmp("set", name))
-          \r {
-          \rERROR1
-              ("[%s] Bad usage of the metacommand set `(usage : set variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(unit);
-          \rreturn;
-          \r}
-        \r
-        else if (!strcmp("setenv", name))
-          \r {
-          \rERROR1
-              ("[%s] Bad usage of the metacommand setenv `(usage : setenv variable=value)'",
-               filepos);
-          \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-          \rfailure(unit);
-          \rreturn;
-          \r}
-        \r\rxbt_os_mutex_acquire(unit->mutex);
-        \r\r
-            /* test if the variable is already registred */ \r
-            xbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-          \rif (!strcmp(variable->name, name))
-            \r {
-            \rexists = 1;
-            \rerr = variable->err;
-            \renv = variable->env;
-            \rbreak;
-            \r}
-        \r}
-        \r\r
-            /* if the variable is already registred, update its value (if same value warns);\r
-             * otherwise register it.\r
-             */ \r
-            if (exists)
-          \r {
-          \rif (err)
-            \r {
-            \rERROR2("[%s] A system variable named `(%s)' already exists",
-                    filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \rfailure(unit);
-            \rreturn;
-            \r}
-          \rif (env)
-            \r {
-            \rERROR2
-                ("[%s] `(%s)' is an environment variable use `setenv' metacommand",
-                 filepos, name);
-            \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-            \rxbt_os_mutex_release(unit->mutex);
-            \r\rfailure(unit);
-            \rreturn;
-            \r}
-          \r
-          else
-            \r {
-            \rif (!strcmp(val, variable->val))
-              \rWARN3("[%s] Variable `(%s)' already contains value `<%s>'",
-                     filepos, variable->name, val);
-            \r\rfree(variable->val);
-            \rvariable->val = strdup(val);
-            \r}
-          \r}
-        \r
-        else
-          \r {
-          \rvariable_t new_var = variable_new(name, val);
-          \rxbt_dynar_push(unit->runner->variables, &new_var);
-          \r}
-        \r\r\rxbt_os_mutex_release(unit->mutex);
-        \r\r}
-      \r
-      else
-        \r {
-        \rif (!strncmp("setenv", line, strlen("setenv")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand setenv : `(usage : setenv variable=value)'",
-               filepos);
-        \r
-        else if (!strncmp("set", line, strlen("set")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand set : `(usage : set variable=value)'",
-               filepos);
-        \r
-        else if (!strncmp("unsetenv", line, strlen("unsetenv")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand unsetenv : `(usage : unsetenv variable)'",
-               filepos);
-        \r
-        else if (!strncmp("unset", line, strlen("unset")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand unset : `(usage : unset variable)'",
-               filepos);
-        \r
-        else if (!strncmp("timeout", line, strlen("timeout")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand timeout : `(usage : timeout <integral positive integer>)'",
-               filepos);
-        \r
-        else if (!strncmp("expect signal", line, strlen("expect signal")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand expect signal : `(usage : expect signal <sig_name>)'",
-               filepos);
-        \r
-        else if (!strncmp("expect return", line, strlen("expect return")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand expect return : `(usage : expect return <return value (>=0 <=255)>)'",
-               filepos);
-        \r
-        else if (!strncmp("include", line, strlen("include")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand include  :`(usage : include <file> [<description>])'",
-               filepos);
-        \r
-        else if (!strncmp("suite", line, strlen("suite")))
-          \rERROR1
-              ("[%s] Bad usage of the metacommand suite : `(usage : suite <description>)'",
-               filepos);
-        \r
-        else
-          \rERROR2("[%s] Unknown metacommand: `%s'", filepos, line);
-        \r\runit_set_error(fstream->unit, ESYNTAX, 1, filepos);
-        \r\rfailure(unit);
-        \rreturn;
-        \r}
-      \r}
-    \r\rbreak;
-    \r}
-\r}
-
-\r\rvoid \r
-fstream_handle_include(fstream_t fstream, context_t context,
-                       xbt_os_mutex_t mutex, const char *file_name,
-                       const char *description) \r
-{
-  \rdirectory_t dir;
-  \rchar *prev_directory = NULL;
-  \rfstream_t _fstream = NULL;
-  \rstruct stat buffer = { 0 };
-  \runit_t unit = fstream->unit;
-  \r\rif (!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
-    \r {
-    \r
-        /* the file is in the current directory */ \r
-        _fstream = fstream_new(getcwd(NULL, 0), file_name);
-    \rfstream_open(_fstream);
-    \r}
-  \r
-      /* the file to include is not in the current directory, check if it is in a include directory */ \r
-      else
-    \r {
-    \runsigned int i;
-    \rprev_directory = getcwd(NULL, 0);
-    \r\rxbt_dynar_foreach(include_dirs, i, dir) \r {
-      \rchdir(dir->name);
-      \r\rif (!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
-        \r {
-        \r_fstream = fstream_new(dir->name, file_name);
-        \rfstream_open(_fstream);
-        \rbreak;
-        \r}
-    \r}
-    \r\rchdir(prev_directory);
-    \rfree(prev_directory);
-    \r}
-  \r\r
-      /* the file to include is not found handle the failure */ \r
-      if (!_fstream)
-    \r {
-    \rif (file_name[0] == '$')
-      \r {
-      \rERROR3
-          ("[%s] Include file `(%s)' not found or variable `(%s)' doesn't exist",
-           context->line, file_name, file_name + 1);
-      \r\r}
-    \r
-    else
-      \r {
-      \r
-          /* may be a variable */ \r
-          variable_t variable;
-      \rint exists = 0;
-      \runsigned int i;
-      \r\rxbt_dynar_foreach(unit->runner->variables, i, variable) \r {
-        \rif (!strcmp(variable->name, file_name))
-          \r {
-          \rexists = 1;
-          \rbreak;
-          \r}
-      \r}
-      \r\rif (exists)
-        \rERROR3
-            ("[%s] Include file `(%s)' not found (if you want to use the variable <%s> add the prefix `$')",
-             context->line, file_name, file_name);
-      \r
-      else
-        \rERROR2("[%s] Include file `(%s)' not found", context->line,
-                file_name);
-      \r}
-    \r\runit_set_error(fstream->unit, EINCLUDENOTFOUND, 1, context->line);
-    \r\rfailure(fstream->unit);
-    \r\rreturn;
-    \r}
-  \r
-  else
-    \r {
-    \rif (!unit->is_running_suite)
-      \r {                       /* it's the unit of a suite */
-      \runit_t include = unit_new(unit->runner, unit->root, unit, _fstream);
-      \r\rinclude->mutex = unit->root->mutex;
-      \r\rif (description)
-        \rinclude->description = strdup(description);
-      \r\rxbt_dynar_push(unit->includes, &include);
-      \r\rif (!dry_run_flag)
-        \r {
-        \rif (description)
-          \rINFO2("Include from %s (%s)", _fstream->name, description);
-        \r
-        else
-          \rINFO1("Include from %s", _fstream->name);
-        \r\r}
-      \r
-      else
-        \rINFO1("Checking include %s...", _fstream->name);
-      \r\rfstream_parse(_fstream, mutex);
-      \r}
-    \r
-    else
-      \r {                       /* it's a include */
-      \r\runit_t * owner;
-      \runit_t include;
-      \r\rowner =
-          xbt_dynar_get_ptr(unit->suites,
-                            xbt_dynar_length(unit->suites) - 1);
-      \r\rinclude = unit_new(unit->runner, unit->root, *owner, _fstream);
-      \r\rinclude->mutex = unit->root->mutex;
-      \r\rif (description)
-        \rinclude->description = strdup(description);
-      \r\rxbt_dynar_push((*owner)->includes, &include);
-      \r\rif (!dry_run_flag)
-        \r {
-        \rif (description)
-          \rINFO2("Include from %s (%s)", _fstream->name, description);
-        \r
-        else
-          \rINFO1("Include from %s", _fstream->name);
-        \r}
-      \r
-      else
-        \rINFO1("Checking include %s...", _fstream->name);
-      \r\rfstream_parse(_fstream, mutex);
-      \r}
-    \r}
-\r}
-
-\r\rvoid \r
-fstream_handle_suite(fstream_t fstream, const char *description,
-                     const char *filepos) \r
-{
-  \runit_t unit = fstream->unit;
-  \runit_t suite = unit_new(unit->runner, unit->root, unit, NULL);
-  \r\rif (description)
-    \rsuite->description = strdup(description);
-  \r\rsuite->filepos = strdup(filepos);
-  \r\rxbt_dynar_push(unit->suites, &suite);
-  \runit->is_running_suite = 1;
-  \r\rif (!dry_run_flag)
-    \rINFO1("Test suite %s", description);
-  \r
-  else
-    \rINFO1("Checking suite %s...", description);
-\r\r}
-
-\r\rint \r
-fstream_launch_command(fstream_t fstream, context_t context,
-                       xbt_os_mutex_t mutex) \r
-{
-  \runit_t unit = fstream->unit;
-  \r\rif (!dry_run_flag)
-    \r {
-    \rcommand_t command;
-    \r\rif (!(command = command_new(unit, context, mutex)))
-      \r {
-      \rif (EINVAL == errno)
-        \r {
-        \rERROR3("[%s] Cannot instantiate the command `%s' (%d)",
-                context->pos, strerror(errno), errno);
-        \r\runit_set_error(unit, errno, 0, context->pos);
-        \rfailure(unit);
-        \rreturn -1;
-        \r}
-      \r
-      else if (ENOMEM == errno)
-        \r {
-        \rERROR3("[%s] Cannot instantiate the command `%s' (%d)",
-                context->pos, strerror(errno), errno);
-        \r\runit_set_error(unit, errno, 0, context->pos);
-        \r\rfailure(unit);
-        \rreturn -1;
-        \r}
-      \r}
-    \r\rif (command_run(command) < 0)
-      \r {
-      \rERROR3("[%s] Cannot run the command `%s' (%d)", context->pos,
-              strerror(errno), errno);
-      \runit_set_error(unit, errno, 0, context->pos);
-      \rfailure(unit);
-      \rreturn -1;
-      \r}
-    \r}
-  \r\rif (context_reset(context) < 0)
-    \r {
-    \rERROR3("[%s] Cannot reset the context of the command `%s' (%d)",
-            context->pos, strerror(errno), errno);
-    \r\runit_set_error(fstream->unit, errno, 0, context->pos);
-    \r\rfailure(unit);
-    \rreturn -1;
-    \r}
-  \r\rreturn 0;
-\r}
-
-\r\r\r\r\r