Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
change the free function by a free_error function to clean all the tesh errors from...
[simgrid.git] / tools / tesh2 / src / main.c
index 94e9599..01aac05 100644 (file)
@@ -1,13 +1,23 @@
-
+/*
+ * src/main.c - this file contains the main function of tesh.
+ *
+ * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. 
+ *
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of the license (GNU LGPL) which comes with this package.
+ *
+ *
+ */
 #include <runner.h>
 #include <fstream.h>
 #include <fstreams.h>
 #include <directory.h>
 #include <directories.h>
 #include <excludes.h>
-#include <error.h>
-
 #include <getopt.h>
+#include <getpath.h>
+
+#include <locale.h>
 
 /*
  * entry used to define the parameter of a tesh option.
@@ -32,7 +42,7 @@ typedef struct s_optentry
 }s_optentry_t,* optentry_t;
 
 
-
+/* logs */
 XBT_LOG_NEW_DEFAULT_CATEGORY(tesh,"TEst SHell utility");
 
 #ifdef WIN32
@@ -41,12 +51,10 @@ static UINT
 prev_error_mode = 0;
 #endif
 
+/* this object represents the root directory */
 directory_t
 root_directory = NULL;
 
-int
-exit_code = 0;
-
 /* the current version of tesh                                                                 */
 static const char* 
 version = "1.0";
@@ -62,22 +70,22 @@ version = "1.0";
 
 /* --jobs is specified with arg                                                                        */
 static int 
-number_of_jobs = -2;
+jobs_nb = -2;
 
 /* --jobs option is not specified (use the default job count)  */
 static int 
-default_number_of_jobs = 1;
+default_jobs_nb = 1;
 
 /* --jobs is specified but has no arg (one job per unit)               */
 static int 
-optional_number_of_jobs = -1;
+optional_jobs_nb = -1;
 
 /* the global timeout                                                                                  */
 static int
 timeout = INDEFINITE;
 
 /* ------------------------------------------------------------ */
-/* strings dlists                                                                                              */
+/* strings                                                                                     */
 /* ------------------------------------------------------------ */
 
 /* --C change the directory before running the units                   */
@@ -85,23 +93,27 @@ static directories_t
 directories = NULL;
 
 /* the include directories : see the !i metacommand                            */
-vector_t 
-includes = NULL;
+/*vector_t 
+include_dirs = NULL;*/
+xbt_dynar_t
+include_dirs = NULL;
 
 /* the list of tesh files to run                                                               */
 static fstreams_t 
 fstreams = NULL;
 
 /* xbt logs                                                                                                            */
-static lstrings_t
+static xbt_dynar_t
 logs = NULL;
 
+/* the list of tesh file suffixes                                                              */
+static xbt_dynar_t
+suffixes = NULL;
+
+
 static excludes_t
 excludes = NULL;
 
-/* the ddlist of tesh file suffixes                                                            */
-static lstrings_t
-suffixes = NULL;
 
 /* ------------------------------------------------------------ */
 /* flags                                                                                                               */
@@ -111,68 +123,66 @@ suffixes = NULL;
  * default value 0 : not keep going
  */
 int 
-want_keep_going = 0;
+keep_going_flag = 0;
 
 /* if 1, ignore failures from commands
  * default value : do not ignore failures
  */
 int 
-want_keep_going_unit = 0;
+keep_going_unit_flag = 0;
 
 /* if 1, display tesh usage                                                                            */
 static int 
-want_display_usage = 0;
+print_usage_flag = 0;
 
 /* if 1, display the tesh version                                                              */
 static int 
-want_display_version = 0;
+print_version_flag = 0;
 
 /* if 1, the syntax of all tesh files is checked 
  * before running them
  */
 static int
-want_check_syntax = 0;
-
-/* if 1, all the tesh file of the current directory
- * are runned
- */ 
-static int
-want_load_directory = 0;
+check_syntax_flag = 0;
 
 /* if 1, the status of all the units is display at
  * the end.
  */
 static int
-want_verbose = 0;
+summary_flag = 0;
+
+/* if 1 and the flag want_summay is set to 1 tesh display the detailed summary of the run */
+int 
+detail_summary_flag = 0;
 
 /* if 1, the directories are displayed                                                 */
 int 
-dont_want_display_directory = 0;
+print_directory_flag = 0;
 
 /* if 1, just check the syntax of all the tesh files
  * do not run them.
  */
 int
-want_dry_run = 0;
+dry_run_flag = 0;
 
 /* if 1, display the tesh files syntax and exit                                        */
 static int
-want_display_semantic = 0;
+print_readme_flag = 0;
 
 int 
-want_silent = 0;
+silent_flag = 0;
 
 int 
-want_just_display = 0;
+just_print_flag = 0;
 
 static int 
-env_overrides  = 0;
+env_overrides_flag  = 0;
 
 static int 
-display_data_base = 0;
+print_database_flag = 0;
 
 static int 
-question = 0;
+question_flag = 0;
 
 /* the semaphore used to synchronize the jobs */
 xbt_os_sem_t
@@ -183,40 +193,54 @@ xbt_os_sem_t
 units_sem = NULL;
 
 static int
-prepared = 0;
+loaded = 0;
 
+int 
+interrupted = 0;
+
+int
+exit_code = 0; 
+
+pid_t
+pid =0;
 
 int 
-interrupted = 0; 
+is_tesh_root = 1;
+
+xbt_dynar_t
+errors = NULL;
+
+xbt_os_mutex_t
+err_mutex = NULL;
 
 /* the table of the entries of the options */ 
 static const struct s_optentry opt_entries[] =
 {
-       { 'C', string, (byte*)&directories, 0, "directory" },
+       { 'C', string, (byte*)NULL, 0, "directory" },
        { 'x', string, (byte*)&suffixes, 0, "suffix" },
-       { 'e', flag, (byte*)&env_overrides, 0, "environment-overrides", },
+       { 'e', flag, (byte*)&env_overrides_flag, 0, "environment-overrides", },
        { 'f', string, (byte*)&fstreams, 0, "file" },
-       { 'h', flag, (byte*)&want_display_usage, 0, "help" },
-       { 'a', flag, (byte*)&want_display_semantic, 0, "semantic" },
-       { 'i', flag, (byte*)&want_keep_going_unit, 0, "keep-going-unit" },
-       { 'I', string, (byte*)&includes, 0, "include-dir" },
-       { 'j', number, (byte*)&number_of_jobs, (byte*) &optional_number_of_jobs, "jobs" },
-       { 'k', flag, (byte*)&want_keep_going, 0, "keep-going" },
-       { 'c', flag, (byte*)&want_just_display, 0, "just-display" },
-       { 'd', flag, (byte*)&display_data_base, 0,"display-data-base" },
-       { 'q', flag, (byte*)&question, 0, "question" },
-       { 's', flag, (byte*)&want_silent, 0, "silent" },
-       { 'V', flag, (byte*)&want_display_version, 0, "version" },
-       { 'w', flag, (byte*)&dont_want_display_directory, 0,"dont-display-directory" },
-       { 'n', flag, (byte*)&want_dry_run, 0, "dry-run"},
+       { 'h', flag, (byte*)&print_usage_flag, 0, "help" },
+       { 'a', flag, (byte*)&print_readme_flag, 0, "semantic" },
+       { 'i', flag, (byte*)&keep_going_unit_flag, 0, "keep-going-unit" },
+       { 'I', string, (byte*)&include_dirs, 0, "include-dir" },
+       { 'j', number, (byte*)&jobs_nb, (byte*) &optional_jobs_nb, "jobs" },
+       { 'k', flag, (byte*)&keep_going_flag, 0, "keep-going" },
+       { 'm', flag, (byte*)&detail_summary_flag, 0, "detail-summary" },
+       { 'c', flag, (byte*)&just_print_flag, 0, "just-print" },
+       { 'd', flag, (byte*)&print_database_flag, 0,"display-data-base" },
+       { 'q', flag, (byte*)&question_flag, 0, "question_flag" },
+       { 's', flag, (byte*)&silent_flag, 0, "silent" },
+       { 'V', flag, (byte*)&print_version_flag, 0, "version" },
+       { 'w', flag, (byte*)&print_directory_flag, 0,"dont-display-directory" },
+       { 'n', flag, (byte*)&dry_run_flag, 0, "dry-run"},
        { 't', number, (byte*)&timeout, 0, "timeout" },
-       { 'S', flag, (byte*)&want_check_syntax, 0, "check-syntax"},
-       { 'r', flag, (byte*)&want_load_directory, 0, "load-directory"},
-       { 'v', flag, (byte*)&want_verbose, 0, "verbose"},
+       { 'S', flag, (byte*)&check_syntax_flag, 0, "check-syntax"},
+       { 'r', string, (byte*)&directories, 0, "load-directory"},
+       { 'v', flag, (byte*)&summary_flag, 0, "summary"},
        { 'F', string,(byte*)&excludes, 0, "exclude"},
        { 'l', string,(byte*)&logs,0,"log"},
        { 0, 0, 0, 0, 0}
-       
 };
 
 /* the tesh usage                                                                                              */
@@ -229,7 +253,7 @@ static const char* usage[] =
        "                                           remark :\n",
        "                                           all argument of the command line without\n",
        "                                           option is dealed as a tesh file.\n",
-       "  -h, --help                            Display this message and exit.\n",
+       "  -h, --help                            Print this message and exit.\n",
        "  -i, --keep-going-unit                 Ignore failures from commands.\n",
        "                                        The possible failures are :\n",
        "                                         - the exit code differ from the expected\n",
@@ -243,22 +267,23 @@ static const char* usage[] =
        "                                        no arg.\n",
        "  -k, --keep-going                      Keep going when some commands can't be made or\n",
        "                                        failed.\n",
-       "  -c, --just-display                    Don't actually run any commands; just display them.\n",
-       "  -p, --display-data-base               Display tesh's internal database.\n",
+       "  -c, --just-print                      Don't actually run any commands; just print them.\n",
+       "  -p, --print-data-base                 Display tesh's internal database.\n",
        "  -q, --question                        Run no commands; exit status says if up to date.\n",
        "  -s, --silent,                         Don't echo commands.\n",
-       "  -V, --version                         Display the version number of tesh and exit.\n",
-       "  -d, --dont-display-directory          Don't display the current directory.\n",
+       "  -V, --version                         Print the version number of tesh and exit.\n",
+       "  -d, --dont-print-directory            Don't display the current directory.\n",
        "  -n, --dry-run                         Check the syntax of the specified tesh files, display the result and exit.\n",
        "  -t, --timeout                         Wait the end of the commands at most timeout seconds.\n",
        "  -S, --check-syntax                    Check the syntax of the tesh files before run them. \n",
        "  -x, --suffix                          Consider the new suffix for the tesh files.\n"
        "                                           remark :\n",
        "                                           the default suffix for the tesh files is \".tesh\".\n",
-       " -a, --semantic                         Display the tesh file metacommands syntax and exit.\n",
+       " -a, --read-me                          Print the read me file and exit.\n",
        " -b, --build-file                       Build a tesh file.\n",
        " -r, --load-directory                   Run all the tesh files located in the directories specified by the option --directory.\n",
-       " -v, --verbose                          Display the status of the commands.\n",
+       " -v, --summary                          Display the status of the commands.\n",
+       " -m, --detail-summary                   Detail the summary of the run.\n",
        " -F file , --exclude=FILE               Ignore the tesh file FILE.\n",
        " -l format, --log                       Format of the xbt logs.\n",
        NULL
@@ -278,132 +303,171 @@ init_options(void);
 static int
 process_command_line(int argc, char** argv);
 
-static int
+static void
 load(void);
 
 static void
-display_usage(int exit_code);
+print_usage(void);
 
 static void
-display_version(void);
+print_version(void);
 
 static void
 finalize(void);
 
 static void
-display_semantic(void);
+print_readme(void);
 
 static int
 init(void);
 
 
+static void 
+sig_abort_handler(int signum)
+{
+       /* TODO : implement this function */
+       INFO0("sig_abort_handler() called");
+}
+
+static void 
+sig_int_handler(int signum)
+{
+       /* TODO : implement this function */
+       INFO0("sig_int_handler() called");
+}
+
+static void 
+free_string(void* str)
+{
+       free(*(void**)str);
+}
+
+static void 
+free_error(void* e)
+{
+       free(*(void**)e);
+}
 
 int
 main(int argc, char* argv[])
 {
-       init();
+       int _argc;
+
+       /* set the locale to the default*/
+       setlocale(LC_ALL,"");
        
+       /* initialize tesh */
+       if(init() < 0)
+               finalize();
+               
        /* process the command line */
-       if((exit_code = process_command_line(argc, argv)))
+       if(process_command_line(argc, argv) < 0)
                finalize();
+       
+       /* move to the root directory (the directory may change during the command line processing) */
+       chdir(root_directory->name);
                
        /* initialize the xbt library 
         * for thread portability layer
         */
         
-       if(!lstrings_is_empty(logs))
+       /* xbt initialization */
+
+       if((_argc = xbt_dynar_length(logs)))
        {
-               int size = lstrings_get_size(logs);
-               char** cstr = lstrings_to_cstr(logs);
-               
-               xbt_init(&size, cstr);
-               
-               free(cstr);
+               int i;
+
+               char** _argv = (char**)calloc(_argc, sizeof(char*));
                
+               for(i = 0; i < _argc; i++)
+                       xbt_dynar_pop(logs, &(_argv[i]));
+
+               xbt_init(&_argc, _argv);
+
+               while(--i)
+                       free(_argv[i]);
+
+               free(_argv);
        }
        else
                xbt_init(&argc, argv);
-       
+               
        /* the user wants to display the usage of tesh */
-       if(want_display_usage)
-               finalize();
+       if(print_version_flag)
+       {
+               print_version();
+
+               if(!print_usage_flag)
+                       finalize();
+       }
        
-       /* the user wants to display the version of tesh */
-       if(want_display_version)
+       /* the user wants to display the usage of tesh */
+       if(print_usage_flag)
        {
-               display_version();
+               print_usage();
                finalize();
        }
        
        /* the user wants to display the semantic of the tesh file metacommands */
-       if(want_display_semantic)
+       if(print_readme_flag)
        {
-               display_semantic();
+               print_readme();
                finalize();
        }
        
-       if(!directories_has_directories_to_load(directories) && want_load_directory)
-               WARN0("--load-directory specified but no directory specified");
+       /* load tesh files */
+       load();
        
-       excludes_check(excludes, fstreams);
        
-       /* load tesh */
-       if((exit_code = load()))
-               finalize();
-               
-       prepared = 1;
+       /* use by the finalize function to known if it must display the tesh usage */   
+       loaded = 1;
 
-       if(-2 == number_of_jobs)
+       if(-2 == jobs_nb)
        {/* --jobs is not specified (use the default value) */
-               number_of_jobs = default_number_of_jobs;
+               jobs_nb = default_jobs_nb;
        }
-       else if(optional_number_of_jobs == number_of_jobs)
+       else if(optional_jobs_nb == jobs_nb)
        {/* --jobs option is specified with no args (use one job per unit) */
-               number_of_jobs = fstreams_get_size(fstreams);
+               jobs_nb = fstreams_get_size(fstreams);
        }
 
-       if(number_of_jobs > fstreams_get_size(fstreams))
+       if(jobs_nb > fstreams_get_size(fstreams))
        {/* --jobs = N is specified and N is more than the number of tesh files */
                
-               WARN0("number of requested jobs exceed the number of files");
+               WARN0("Number of requested jobs exceed the number of files to run");
                
                /* assume one job per file */
-               number_of_jobs = fstreams_get_size(fstreams);
+               jobs_nb = fstreams_get_size(fstreams);
        }
 
-       /* initialize the semaphore used to synchronize the jobs */
-       jobs_sem = xbt_os_sem_init(number_of_jobs);
+       /* initialize the semaphore used to synchronize all the units */
+       jobs_sem = xbt_os_sem_init(jobs_nb);
 
        /* initialize the semaphore used by the runner to wait for the end of all units */
        units_sem = xbt_os_sem_init(0);
        
        /* initialize the runner */
-       if((0 != (exit_code = runner_init(
-                                                                       want_check_syntax, 
-                                                                       timeout, 
-                                                                       fstreams))))
-       {
+       if(runner_init(check_syntax_flag, timeout, fstreams) < 0)
                finalize();
-       }
-       
-       if(want_just_display && want_silent)
-               want_silent = 0;
                
-       if(want_just_display && want_dry_run)
+       if(just_print_flag && silent_flag)
+               silent_flag = 0;
+               
+       if(just_print_flag && dry_run_flag)
                WARN0("mismatch in the syntax : --just-check-syntax and --just-display options at same time");
        
        /* run all the units */
-       runner_run(); 
+       runner_run();
+       
        
        /* show the result of the units */
-       if(want_verbose || want_dry_run)
-               runner_display_status();
+       if(summary_flag || dry_run_flag)
+               runner_summarize();
                
-
        /* all the test are runned, destroy the runner */
        runner_destroy();
        
-       /* then, finalize tesh */
+       /* then, finalize tesh (release all the allocated memory and exits) */
        finalize();
        
        #ifndef WIN32
@@ -412,10 +476,20 @@ main(int argc, char* argv[])
        
 }
 
+/* init --     initialize tesh : allocated all the objects needed by tesh to run
+ *                     the tesh files specified in the command line.
+ *
+ * return      If successful the function returns zero. Otherwise the function returns
+ *                     -1 and sets the global variable errno to the appropriate error code.
+ */
+
+
+
 static int
 init(void)
 {
-       char* buffer = getcwd(NULL, 0);
+       char* buffer;
+       char* suffix = strdup(".tesh");
        
        #ifdef WIN32
        /* Windows specific : don't display the general-protection-fault message box and
@@ -423,158 +497,265 @@ init(void)
         * to the calling process : tesh)
         */
        prev_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
-       #endif
+       #else
+       struct sigaction act;
+       /* Ignore pipe issues.
+        * They will show up when we try to send data to dead buddies, 
+     * but we will stop doing so when we're done with provided input 
+     */
+       memset(&act,0, sizeof(struct sigaction));
+       act.sa_handler = SIG_IGN;
+       sigaction(SIGPIPE, &act, NULL);
+       
+       
+       memset(&act,0, sizeof(struct sigaction));
+       act.sa_handler = sig_abort_handler;
+       sigaction(SIGABRT, &act, NULL);
+       
+       memset(&act,0, sizeof(struct sigaction));
+       act.sa_handler = sig_int_handler;
+       sigaction(SIGINT, &act, NULL);
+       
+       #endif
+       
+       err_mutex = xbt_os_mutex_init();
+       
+       /* handle the abort signal */
+       /*signal(SIGABRT, sig_abort_handler);*/
+       
+       /* handle the interrupt signal */
+       /*signal(SIGINT, sig_int_handler);*/
        
-       /* used to store the file streams to run */
-       fstreams = fstreams_new(DEFAULT_FSTREAMS_CAPACITY, fstream_free);
+       /* used to store the files to run */
+       if(!(fstreams = fstreams_new(DEFAULT_FSTREAMS_CAPACITY, (void_f_pvoid_t)fstream_free)))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
+       
+       /* register the current directory */
+       if(!(buffer  = getcwd(NULL, 0)))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
+       
+       /* save the root directory */
+       if(!(root_directory = directory_new(buffer)))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
        
-       root_directory = directory_new(buffer,want_load_directory);
        free(buffer);
-       /* used to store the directories to loads */
-       directories = directories_new(); 
        
-       /* register the current directory */
-       directories_add(directories, root_directory);
+       /* this vector contains all the errors of the run */
+       errors = xbt_dynar_new(sizeof(xerror_t), free_error);
        
-       /* used to store the includes directories */
-       includes = vector_new(DEFAULT_INCLUDES_CAPACITY, directory_free);
+       /* the directories to loads */
+       if(!(directories = directories_new()))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
        
-       /* xbt logs */
-       logs = lstrings_new();
+       /* the include directories */
+       include_dirs = xbt_dynar_new(sizeof(directory_t), (void_f_pvoid_t)directory_free);
        
-       /* used to to store all the excluded file streams */
-       excludes = excludes_new();
+       /* xbt logs option */
+       if(!(logs = xbt_dynar_new(sizeof(char*), free_string)))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
        
-       /* list of file streams suffixes */
-       suffixes = lstrings_new();
+       /* the excluded files */
+       if(!(excludes = excludes_new()))
+       {
+               ERROR1("(system error) %s", strerror(errno));
+               return -1;
+       }
+       
+       /* the suffixes */
+       suffixes = xbt_dynar_new(sizeof(char*),free_string);
        
-       lstrings_push_back(suffixes,".tesh");
+       /* register the default suffix ".tesh" */
+       xbt_dynar_push(suffixes, &suffix);
        
        return 0;
 }
 
-static int
+/* load -- load the tesh files to run */
+static void
 load(void)
 {
-       chdir(directory_get_name(root_directory));
        
-       if(want_load_directory)
+       /* if the directories object is not empty load all the tesh files contained in
+        * the directories specified in the command line (this tesh files must have the
+        * a suffix specified in the suffixes object.
+        */
+       if(!directories_is_empty(directories))
                directories_load(directories, fstreams, suffixes);
        
-       /* on a aucun fichier specifie dans la ligne de commande
-        * l'option --run-current-directory n'a pas ete specifie ou aucun fichier ne se trouve dans le repertoire a charger
+       /* if no tesh file has been specified in the command line try to load the default tesh file
+        * teshfile from the current directory
         */
        if(fstreams_is_empty(fstreams))
        {
                struct stat buffer = {0};
                
-               /* add the default tesh file if it exists */
+               /* add the default tesh file if it exists in the current directory */
                if(!stat("teshfile", &buffer) && S_ISREG(buffer.st_mode))
                        fstreams_add(fstreams, fstream_new(getcwd(NULL, 0), "teshfile"));
        }
        
+       /* excludes the files specified in the command line and stored in the excludes object */
        if(!excludes_is_empty(excludes) && !fstreams_is_empty(fstreams))
+       {
+               /* check the files to excludes before */        
+               excludes_check(excludes, fstreams);
+               
+               /* exclude the specified tesh files */
                fstreams_exclude(fstreams, excludes);
+       }
        
+       /* if the fstreams object is empty use the stdin */
        if(fstreams_is_empty(fstreams))
-               fstreams_add(fstreams, fstream_new(NULL, "stdin"));     
+               fstreams_add(fstreams, fstream_new(NULL, "stdin"));
        
+       /* load the tesh files (open them) */
        fstreams_load(fstreams);
        
-       return 0;
 }
 
+/* finalize -- cleanup all the allocated objects and display the tesh usage if needed */
 static void
 finalize(void)
 {
-       if((!exit_code && want_display_usage) || (!exit_code && !prepared))
-               display_usage(exit_code);
        
+       if(is_tesh_root && !summary_flag)
+       {
+               xerror_t error;
+               unsigned int i;
+
+               xbt_dynar_foreach(errors, i, error)
+               {
+                       if(error->command)
+                               fprintf(stderr, "[tesh/ERROR] %s : <Command `%s'> <Unit `%s'> <C%d (%s)>\n", error->reason, error->command, error->unit, error->errcode, error_to_string(error->errcode));
+                       else if(!error->command && error->unit)
+                               fprintf(stderr, "[tesh/ERROR] %s : Unit `%s' - C%d (%s)\n", error->reason, error->unit, error->errcode, error_to_string(error->errcode));
+                       else if(!error->command && !error->unit && error->reason)
+                               fprintf(stderr, "[tesh/ERROR] %s : C%d (%s)\n", error->reason, error->errcode, error_to_string(error->errcode));                
+                       else if(!error->command && !error->unit && !error->reason)
+                               fprintf(stderr, "[tesh/ERROR] C%d (%s)\n", error->errcode, error_to_string(error->errcode));            
+                       
+               }
+       }
+       
+       
+       /* delete vector of errors */
+       if(errors)
+               xbt_dynar_free(&errors);
+               
+       xbt_os_mutex_destroy(err_mutex);
+       
+       /* delete the fstreams object */
        if(fstreams)
                fstreams_free((void**)&fstreams);
        
+       /* delete the excludes object */
        if(excludes)    
                excludes_free((void**)&excludes);
        
+       /* delete the directories object */
        if(directories)
                directories_free((void**)&directories);
-       
-       if(includes)
-               vector_free(&includes);
                
+       /* delete the root directory object */
+       if(root_directory)
+               directory_free((void**)&root_directory);
+       
+       /* delete the include directories object */
+       if(include_dirs)
+               xbt_dynar_free(&include_dirs);
+       
+       /* delete the list of tesh files suffixes */    
        if(suffixes)
-               lstrings_free(&suffixes);
+               xbt_dynar_free(&suffixes);
        
+       /* delete the xbt log options list */
        if(logs)
-               lstrings_free(&logs);
-       
-       /* destroy the semaphore used to synchronize the jobs */
+               xbt_dynar_free(&logs);
+               
+               
+       /* destroy the semaphore used to synchronize the units */
        if(jobs_sem)
                xbt_os_sem_destroy(jobs_sem);
-
+       
+       /* destroy the semaphore used by the runner used to wait for the end of the units */
        if(units_sem)
                xbt_os_sem_destroy(units_sem);
        
        /* exit from the xbt framework */
        xbt_exit();
        
+       /* Windows specific (restore the previouse error mode */
        #ifdef WIN32
        SetErrorMode(prev_error_mode);
        #endif
        
-       if(!want_verbose && !want_dry_run && !want_silent && !want_just_display)
-               INFO2("tesh terminated with exit code %d : %s",exit_code, (!exit_code ? "success" : error_to_string(exit_code)));
+       if(!summary_flag && !dry_run_flag && !silent_flag && !just_print_flag && !print_version_flag && !print_usage_flag && is_tesh_root)
+       {
+               if(!exit_code)
+                       INFO2("tesh terminated with exit code %d : %s",exit_code, "success");
+               else
+                       ERROR2("tesh terminated with exit code %d : %s",exit_code, error_to_string(exit_code));
+       }
+       
        
+       /* exit with the last error code */
        exit(exit_code);
 }
 
+/* init_options -- initialize the options string */
 static void
 init_options (void)
 {
        char *p;
        unsigned int i;
        
+       /* the function has been already called */
        if(optstring[0] != '\0')
-       /* déjà traité.  */
                return;
        
        p = optstring;
        
-       /* Return switch and non-switch args in order, regardless of
-       POSIXLY_CORRECT.  Non-switch args are returned as option 1.  */
-       
-       /* le premier caractère de la chaîne d'options vaut -.
-        * les arguments ne correspondant pas Ã  une option sont 
-        * manipulés comme s'ils Ã©taient des arguments d'une option
-        *  dont le caractère est le caractère de code 1
-        */
        *p++ = '-';
        
        for (i = 0; opt_entries[i].c != '\0'; ++i)
        {
-               /* initialize le nom de l'option longue*/
+               /* initialize the long name of the option*/
                longopts[i].name = (opt_entries[i].long_name == 0 ? "" : opt_entries[i].long_name);
                
-               /* getopt_long() retourne la valeur de val */
+               /* getopt_long returns the value of val */
                longopts[i].flag = 0;
                
-               /* la valeur de l'option courte est le caractère spécifié dans  opt_entries[i].c */
+               /* the short option */
                longopts[i].val = opt_entries[i].c;
                
-               /* on l'ajoute Ã  la chaine des optstring */
+               /* add the short option in the options string */
                *p++ = opt_entries[i].c;
                
                switch (opt_entries[i].type)
                {
-                       /* si c'est une option qui sert a positionner un flag ou que l'on doit ignorée, elle n'a pas d'argument */
+                       /* if this option is used to set a flag or if the argument must be ignored
+                        * the option has no argument
+                        */
                        case flag:
                        longopts[i].has_arg = no_argument;
                        break;
                
-                       /* c'est une option qui attent un argument : 
-                        * une chaine de caractères, un nombre flottant, 
-                        * ou un entier positif
-                        */
+                       /* the option has an argument */
                        case string:
                        case number:
                        
@@ -597,6 +778,18 @@ init_options (void)
        longopts[i].name = 0;
 }
 
+/* process_command_line --     process the command line
+ *
+ * param                                       argc the number of the arguments contained by the command line.
+ * param                                       The array of C strings containing all the arguments of the command 
+ *                                                     line.
+ *
+ * return                                      If successful, the function returns 0. Otherwise -1 is returned
+ *                                                     and sets the global variable errno to indicate the error.
+ *
+ * errors      [ENOENT]                A file name specified in the command line does not exist
+ */    
+
 static int
 process_command_line(int argc, char** argv)
 {
@@ -605,17 +798,18 @@ process_command_line(int argc, char** argv)
        directory_t directory;
        fstream_t fstream;
        
-       /* initialize the options table of tesh */
+       /* initialize the options string of tesh */
        init_options();
        
-       /* display the errors of the function getopt_long() */
+       /* let the function getopt_long display the errors if any */
        opterr = 1;
        
+       /* set option index to zero */
        optind = 0;
        
        while (optind < argc)
        {
-               c = getopt_long (argc, argv, optstring, longopts, (int *) 0);
+               c = getopt_long(argc, argv, optstring, longopts, (int *) 0);
                
                if(c == EOF)
                {
@@ -624,72 +818,56 @@ process_command_line(int argc, char** argv)
                }
                else if (c == 1)
                {
-                       /* the argument of the command line is not an option (no "-"), assume it's a tesh file */
-                       /*struct stat buffer = {0};
-                       char* prev = getcwd(NULL, 0);
+                       /* no option specified, assume it's a tesh file to run */
+                       char* path;
+                       char* delimiter;
                        
-                       directory = directories_get_back(directories);
-                       
-                       chdir(directory->name);
-                       
-                       if(stat(optarg, &buffer) || !S_ISREG(buffer.st_mode))
+                       /* getpath returns -1 when the file to get the path doesn't exist */
+                       if(getpath(optarg, &path) < 0)
                        {
-                               chdir(prev);
-                               free(prev);
-                               ERROR1("file %s not found", optarg);
-                               return EFILENOTFOUND;
+                               exit_code = errno;
+                               
+                               if(ENOENT == errno)
+                                       ERROR1("File %s does not exist", optarg);
+                               else
+                                       ERROR0("Insufficient memory is available to parse the command line : system error");
+                                       
+                               return -1;
                        }
                        
-                       chdir(prev);
-                       free(prev);*/
+                       /* get to the last / (if any) to get the short name of the file */
+                       delimiter = strrchr(optarg,'/');
                        
-                       directory = directories_search_fstream_directory(directories, optarg);
+                       /* create a new file stream which represents the tesh file to run */
+                       fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
                        
-                       if(!directory)
-                       {
-                               if(1 == directories_get_size(directories))
-                               {
-                                       ERROR1("file %s not found in the current directory",optarg);
-                                       return EFILENOTINCURDIR;
-                               }
-                               else
-                               {
-                                       ERROR1("file %s not found in the specified directories",optarg);
-                                       return EFILENOTINSPECDIR;
-                               }
-                       }
+                       free(path);
                        
-                       if(!(fstream = fstream_new(directory_get_name(directory), optarg)))
+                       /* if the list of all tesh files to run already contains this file
+                        * destroy it and display a warning, otherwise add it in the list.
+                        */
+                       if(fstreams_contains(fstreams, fstream))
                        {
-                               ERROR1("command line processing failed with the error code %d", errno);
-                               return EPROCESSCMDLINE;
+                               fstream_free(&fstream);
+                               WARN1("File %s already specified to be run", optarg);
                        }
                        else
-                       {
-                               if(fstreams_contains(fstreams, fstream))
-                               {
-                                       fstream_free((void**)&fstream);
-                                       WARN1("file %s already specified", optarg);
-                               }
-                               else
-                               {
-                                       if((errno = fstreams_add(fstreams, fstream)))
-                                       {
-                                               fstream_free((void**)&fstream);
-                                               ERROR1("command line processing failed with the error code %d", errno);
-                                               return EPROCESSCMDLINE;
-                                       }
-                               }
-                       }                                       
+                               fstreams_add(fstreams, fstream);
+                               
+                       
+                               
+                       
                }
                else if (c == '?')
                {
-                       /* unknown option, getopt_long() displays the error */
-                       return 1;
+                       /* unknown option, let getopt_long() displays the error */
+                       ERROR0("Command line processing failed : invalid command line");
+                       exit_code = EINVCMDLINE;
+                       return -1;
                }
                else
                {
-                       for (entry = opt_entries; entry->c != '\0'; ++entry)
+                       for(entry = opt_entries; entry->c != '\0'; ++entry)
                                
                                if(c == entry->c)
                                {
@@ -698,8 +876,9 @@ process_command_line(int argc, char** argv)
                                        {
                                                /* impossible */
                                                default:
-                                               ERROR0("command line processing failed : internal error");
-                                               return EPROCESSCMDLINE;
+                                               ERROR0("Command line processing failed : internal error");
+                                               exit_code = EPROCCMDLINE;
+                                               return -1;
                                                
                                                
                                                /* flag options */
@@ -720,212 +899,300 @@ process_command_line(int argc, char** argv)
                                                else if (*optarg == '\0')
                                                {
                                                        /* a non optional argument is not specified */
-                                                       ERROR2("the option %c \"%s\"requires an argument",entry->c,entry->long_name);
-                                                       return EARGNOTSPEC;
+                                                       ERROR2("Option %c \"%s\"requires an argument",entry->c,entry->long_name);
+                                                       exit_code = ENOARG;
+                                                       return -1;
                                                }
                                                
-                                               /* --directory option */
-                                               if(!strcmp(entry->long_name,"directory"))
+                                               /* --load-directory option */
+                                               if(!strcmp(entry->long_name,"load-directory"))
                                                {
-                                                       if(!(directory = directory_new(optarg, want_load_directory)))
+                                                       #ifdef WIN32
+                                                       struct stat info = {0};
+                                                       if(stat(optarg, &info) || !S_ISDIR(info.st_mode))
+                                                       {
+                                                               ERROR1("%s is not a directory",optarg);
+                                                               exit_code = ENOTDIR;
+                                                               return -1;
+                                                       }       
+
+                                                       #else
+                                                       char* path;
+                                                       
+                                                       if(translatepath(optarg, &path) < 0)
                                                        {
+                                                               exit_code = errno;
+                                                               
                                                                if(ENOTDIR == errno)
-                                                               {
-                                                                       ERROR1("directory %s not found",optarg);
-                                                                       return EDIRNOTFOUND;
-                                                               }
+                                                                       ERROR1("%s is not a directory",optarg);
                                                                else
-                                                               {
-                                                                       ERROR1("command line processing failed with the error code %d", errno);
-                                                                       return EPROCESSCMDLINE;
-                                                               }
+                                                                       ERROR0("Insufficient memory is available to process the command line - system error");
+                                                                       
+                                                               return -1;
+                                                               
                                                        }
+                                                       #endif
                                                        else
                                                        {
+                                                               #ifdef WIN32
+                                                               directory = directory_new(optarg);
+                                                               #else
+                                                               directory = directory_new(path);
+                                                               free(path);
+                                                               #endif
+                                               
                                                                if(directories_contains(directories, directory))
                                                                {
                                                                        directory_free((void**)&directory);
-                                                                       WARN1("directory %s already specified",optarg);
+                                                                       WARN1("Directory %s already specified to be load",optarg);
                                                                }
                                                                else
-                                                               {
-                                                                       if((errno = directories_add(directories, directory)))
-                                                                       {
-                                                                               directory_free((void**)&directory);
-                                                                               ERROR1("command line processing failed with the error code %d", errno);
-                                                                               return EPROCESSCMDLINE;
-                                                                       }
-                                                               }
+                                                                        directories_add(directories, directory);
+                                                                        
+                                                               
                                                        }                       
                                                }
+                                               else if(!strcmp(entry->long_name,"directory"))
+                                               {
+                                                       #ifdef WIN32
+                                                       struct stat info = {0};
+                                                       if(stat(optarg, &info) || !S_ISDIR(info.st_mode))
+                                                       {
+                                                               ERROR1("%s is not a directory",optarg);
+                                                               exit_code = ENOTDIR;
+                                                               return -1;
+                                                       }       
+
+                                                       #else
+                                                       char* path ;
+                                                       
+                                                       if(translatepath(optarg, &path) < 0)
+                                                       {
+                                                               exit_code = errno;
+                                                               
+                                                               if(ENOTDIR == errno)
+                                                                       ERROR1("%s is not a directory",optarg);
+                                                               else
+                                                                       ERROR0("Insufficient memory is available to process the command line - system error");
+                                                                       
+                                                               return -1;
+                                                       }
+                                                       #endif
+                                                       else
+                                                       {
+                                                               char* buffer = getcwd(NULL, 0);
+
+                                                               #ifdef WIN32
+                                                               
+                                                               if(!strcmp(buffer, optarg))
+                                                                       WARN1("Already in the directory %s", optarg);
+                                                               else if(!print_directory_flag)
+                                                                       INFO1("Entering directory \"%s\"",optarg);
+                                                               
+                                                               chdir(optarg);
+                                                               #else
+                                                               
+                                                               if(!strcmp(buffer, path))
+                                                                       WARN1("Already in the directory %s", optarg);
+                                                               else if(!print_directory_flag)
+                                                                       INFO1("Entering directory \"%s\"",path);
+
+                                                               chdir(path);
+                                                               free(path);
+                                                               #endif
+
+                                                               free(buffer);
+                                                               
+                                                               
+                                                       }       
+                                               }
+                                               
                                                /* --suffix option */
                                                else if(!strcmp(entry->long_name,"suffix"))
                                                {
                                                        if(strlen(optarg) > MAX_SUFFIX)
                                                        {
-                                                               ERROR1("suffix %s too long",optarg);
-                                                               return ESUFFIXTOOLONG;  
+                                                               ERROR1("Suffix %s too long",optarg);
+                                                               exit_code = ESUFFIXTOOLONG;     
+                                                               return -1;
                                                        }
                                                        
                                                        if(optarg[0] == '.')
                                                        {
+                                                               char* cur;
+                                                               unsigned int i;
+                                                               int exists = 0;
+
                                                                char suffix[MAX_SUFFIX + 2] = {0};
                                                                sprintf(suffix,".%s",optarg);
                                                                
-                                                               if(lstrings_contains(suffixes, suffix))
-                                                                       WARN1("suffix %s already specified", optarg);
+                                                               xbt_dynar_foreach(suffixes, i, cur)
+                                                               {
+                                                                       if(!strcmp(suffix, cur))
+                                                                       {
+                                                                               exists = 1;
+                                                                               break;
+                                                                       }
+                                                               }
+
+                                                               if(exists)
+                                                                       WARN1("Suffix %s already specified to be used", optarg);
                                                                else
-                                                                       lstrings_push_back(suffixes, suffix);
+                                                                       xbt_dynar_push(suffixes, &suffix);
                                                        }
                                                        else
                                                        {
-                                                               if(lstrings_contains(suffixes, optarg))
-                                                                       WARN1("suffix %s already specified", optarg);
+                                                               char* cur;
+                                                               unsigned int i;
+                                                               int exists = 0;
+
+                                                               xbt_dynar_foreach(suffixes, i, cur)
+                                                               {
+                                                                       if(!strcmp(optarg, cur))
+                                                                       {
+                                                                               exists = 1;
+                                                                               break;
+                                                                       }
+                                                               }
+
+                                                               if(exists)
+                                                                       WARN1("Suffix %s already specified to be used", optarg);
                                                                else
-                                                                       lstrings_push_back(suffixes, optarg);   
+                                                                       xbt_dynar_push(suffixes, &optarg);      
                                                        }
                                                }
                                                /* --file option */
                                                else if(!strcmp(entry->long_name,"file"))
                                                {
+                                                       char* path;
+                                                       char* delimiter;
                                                        
-                                                       /* the argument of the command line is not an option (no "-"), assume it's a tesh file */
-                                                       /*struct stat buffer = {0};
-                                                       char* prev = getcwd(NULL, 0);
-                                                       
-                                                       directory = directories_get_back(directories);
-                                                       
-                                                       chdir(directory->name);
-                       
-                                                       if(stat(optarg, &buffer) || !S_ISREG(buffer.st_mode))
+                                                       if(getpath(optarg, &path) < 0)
                                                        {
-                                                               chdir(prev);
-                                                               free(prev);
-                                                               ERROR1("file %s not found", optarg);
-                                                               return EFILENOTFOUND;
+                                                               exit_code = errno;
+                                                               
+                                                               if(ENOENT == errno)
+                                                                       ERROR1("File %s does not exist", optarg);
+                                                               else
+                                                                       ERROR0("Insufficient memory is available to process the command line - system error");
+                                                               
+                                                               return -1;
                                                        }
                                                        
-                                                       chdir(prev);
-                                                       free(prev);*/
+                                                       delimiter = strrchr(optarg,'/');
                                                        
-                                                       directory = directories_search_fstream_directory(directories, optarg);
-                       
-                                                       if(!directory)
-                                                       {
-                                                               if(1 == directories_get_size(directories))
-                                                               {
-                                                                       ERROR1("file %s not found in the current directory",optarg);
-                                                                       return EFILENOTINCURDIR;
-                                                               }
-                                                               else
-                                                               {
-                                                                       ERROR1("file %s not found in the specified directories",optarg);
-                                                                       return EFILENOTINSPECDIR;
-                                                               }
-                                                       }
+                                                       fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
+                                                       
+                                                       free(path);
                                                        
-                                                       if(!(fstream = fstream_new(directory_get_name(directory),optarg)))
+                                                       if(fstreams_contains(fstreams, fstream))
                                                        {
-                                                               ERROR1("command line processing failed with the error code %d", errno);
-                                                               return EPROCESSCMDLINE;
+                                                               fstream_free(&fstream);
+                                                               WARN1("File %s already specified to run", optarg);
                                                        }
                                                        else
-                                                       {
-                                                               if(fstreams_contains(fstreams, fstream))
-                                                               {
-                                                                       fstream_free((void**)&fstream);
-                                                                       WARN1("file %s already specified", optarg);
-                                                               }
-                                                               else
-                                                               {
-                                                                       if((errno = fstreams_add(fstreams, fstream)))
-                                                                       {
-                                                                               fstream_free((void**)&fstream);
-                                                                               ERROR1("command line processing failed with the error code %d", errno);
-                                                                               return EPROCESSCMDLINE;
-                                                                       }
-                                                               }
-                                                       }               
+                                                               fstreams_add(fstreams, fstream);
                                                }
                                                /* --include-dir option */
                                                else if(!strcmp(entry->long_name,"include-dir"))
                                                {
-                                                       if(!(directory = directory_new(optarg, want_load_directory)))
+                                                       #ifdef WIN32
+                                                       struct stat info = {0};
+                                                       if(stat(optarg, &info) || !S_ISDIR(info.st_mode))
+                                                       {
+                                                               ERROR1("%s is not a directory",optarg);
+                                                               exit_code = ENOTDIR;
+                                                               return -1;
+                                                       }       
+
+                                                       #else
+                                                       char* path ;
+                                                       
+                                                       if(translatepath(optarg, &path) < 0)
                                                        {
+                                                               exit_code = errno;
+                                                               
                                                                if(ENOTDIR == errno)
-                                                               {
                                                                        ERROR1("%s is not a directory",optarg);
-                                                                       return EDIRNOTFOUND;
-                                                               }
                                                                else
-                                                               {
-                                                                       ERROR1("command line processing failed with the error code %d", errno);
-                                                                       return EPROCESSCMDLINE;
-                                                               }
+                                                                       ERROR0("Insufficient memory is available to process the command line - system error");
+                                                                       
+                                                               return -1;
                                                        }
+                                                       #endif
                                                        else
                                                        {
-                                                               if(vector_contains(includes, directory))
+                                                               int exists = 0;
+                                                               unsigned int i;
+                                                               directory_t cur;
+                                                               #ifdef WIN32
+                                                               directory = directory_new(optarg);
+                                                               #else
+                                                               directory = directory_new(path);
+                                                               free(path);
+                                                               #endif
+
+                                                               xbt_dynar_foreach(include_dirs, i , cur)
+                                                               {
+                                                                       if(!strcmp(cur->name, optarg))
+                                                                       {
+                                                                               exists = 1;
+                                                                               break;
+                                                                       }
+                                                               }
+
+                                                               if(exists)
                                                                {
                                                                        directory_free((void**)&directory);
-                                                                       WARN1("include directory %s already specified",optarg);
+                                                                       WARN1("Include directory %s already specified to be used",optarg);
                                                                        
                                                                }
                                                                else
-                                                               {
-                                                                       if((errno = vector_push_back(includes, directory)))
-                                                                       {
-                                                                               directory_free((void**)&directory);
-                                                                               ERROR1("command line processing failed with the error code %d", errno);
-                                                                               return EPROCESSCMDLINE;
-                                                                       }
-                                                               }
+                                                                       xbt_dynar_push(include_dirs, &directory);
+
                                                        }
                                                }
                                                /* --exclude option */ 
                                                else if(!strcmp(entry->long_name,"exclude"))
                                                {
-                                                       directory = directories_get_back(directories);
-                                                       
-                                                       if(!(fstream = fstream_new(directory_get_name(directory), optarg)))
+                                                       char* path;
+                                                       char* delimiter;
+                       
+                                                       if(getpath(optarg, &path) < 0)
                                                        {
+                                                               exit_code = errno;
+                                                               
                                                                if(ENOENT == errno)
-                                                               {
-                                                                       ERROR1("file to exclude %s not found", optarg);
-                                                                       return EFILENOTFOUND;
-                                                               }
+                                                                       ERROR1("file %s does not exist", optarg);
                                                                else
-                                                               {
-                                                                       ERROR1("command line processing failed with the error code %d", errno);
-                                                                       return EPROCESSCMDLINE;
-                                                               }
+                                                                       ERROR0("Insufficient memory is available to process the command line - system error");
+                                                                       
+                                                               return -1;
                                                        }
-                                                       else
+                       
+                                                       delimiter = strrchr(optarg,'/');
+                       
+                                                       fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
+                                                       free(path);
+                       
+                                                       if(excludes_contains(excludes, fstream))
                                                        {
-                                                               if(excludes_contains(excludes, fstream))
-                                                               {
-                                                                       fstream_free((void**)&fstream);
-                                                                       WARN1("file to exclude %s already specified", optarg);
-                                                               }
-                                                               else
-                                                               {
-                                                                       if((errno = excludes_add(excludes, fstream)))
-                                                                       {
-                                                                               fstream_free((void**)&fstream);
-                                                                               ERROR1("command line processing failed with the error code %d", errno);
-                                                                               return EPROCESSCMDLINE;
-                                                                       }
-                                                               }
-                                                       }                               
+                                                               fstream_free(&fstream);
+                                                               WARN1("File %s already specified to be exclude", optarg);
+                                                       }
+                                                       else
+                                                               excludes_add(excludes, fstream);
+                                                                       
                                                }
                                                /* --log option */
                                                else if(!strcmp(entry->long_name,"log"))
                                                {
-                                                       lstrings_push_back(logs, optarg);
+                                                       xbt_dynar_push(logs, &optarg);
                                                }
                                                else
                                                {
-                                                       /* TODO */
+                                                       INFO1("Unexpected option %s", optarg);
+                                                       return -1;
                                                }
                                                
                                                
@@ -953,8 +1220,9 @@ process_command_line(int argc, char** argv)
                
                                                        if (i < 1 || cp[0] != '\0')
                                                        {
-                                                               ERROR2("option %c \"%s\" requires an strictly positive integer as argument",entry->c, entry->long_name);
-                                                               return ENOTPOSITIVENUM;
+                                                               ERROR2("Option %c \"%s\" requires an strictly positive integer as argument",entry->c, entry->long_name);
+                                                               exit_code = ENOTPOSITIVENUM;
+                                                               return -1;
                                                        }
                                                        else
                                                                *(int*)entry->value = i;
@@ -975,14 +1243,11 @@ process_command_line(int argc, char** argv)
 }
 
 static void
-display_usage(int exit_code)
+print_usage(void)
 {
        const char **cpp;
        FILE* stream;
        
-       if (want_display_version)
-               display_version();
-       
        stream = exit_code ? stderr : stdout;
        
        fprintf (stream, "Usage: tesh [options] [file] ...\n");
@@ -994,7 +1259,7 @@ display_usage(int exit_code)
 }
 
 static void
-display_version(void)
+print_version(void)
 {
        /* TODO : display the version of tesh */
        printf("Version :\n");
@@ -1005,12 +1270,12 @@ display_version(void)
        printf("  This program is free software; you can redistribute it and/or modify it\n");
        printf("  under the terms of the license (GNU LGPL) which comes with this package.\n\n");
        
-       if(!want_display_usage)
+       if(!print_usage_flag)
                printf("Report bugs to <martin.quinson@loria.fr | malek.cherier@loria.fr>");
 }
 
 static void
-display_semantic(void)
+print_readme(void)
 {
        size_t len;
        char * line = NULL;