+++ /dev/null
-#ifndef __SIGNAL_H
-#define __SIGNAL_H
-
-#include <signal.h>
-#include <types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef WIN32
-
-/* terminal line hangup */
-#ifndef SIGHUP
-#define SIGHUP 1
-#endif
-
-/* interrupt program */
-#ifndef SIGINT
-#define SIGINT 2
-#endif
-
-/* quit program */
-#ifndef SIGQUIT
-#define SIGQUIT 3
-#endif
-
-/* illegal instruction */
-#ifndef SIGILL
-#define SIGILL 4
-#endif
-
-/* trace trap */
-#ifndef SIGTRAP
-#define SIGTRAP 5
-#endif
-
-/* abnormal termination triggered by abort call */
-#ifndef SIGABRT
-#define SIGABRT 6
-#endif
-
-/* floating point exception */
-#ifndef SIGFPE
-#define SIGFPE 8
-#endif
-
-/* kill program */
-#ifndef SIGKILL
-#define SIGKILL 9
-#endif
-
-/* bus error */
-#ifndef SIGBUS
-#define SIGBUS 10
-#endif
-
-/* segment violation */
-#ifndef SIGSEGV
-#define SIGSEGV 11
-#endif
-
-/* non-existent system call invoked */
-#ifndef SIGSYS
-#define SIGSYS 12
-#endif
-
-/* write on a pipe with no reader */
-#ifndef SIGPIPE
-#define SIGPIPE 13
-#endif
-
-/* real-time timer expired */
-#ifndef SIGALRM
-#define SIGALRM 14
-#endif
-
-/* software termination signal from kill */
-#ifdef SIGTERM
-#define SIGTERM 15
-#endif
-
-/* urgent condition present on socket */
-#ifndef SIGURG
-#define SIGURG 16
-#endif
-
-/* stop (cannot be caught orignored) */
-#ifndef SIGSTOP
-#define SIGSTOP 17
-#endif
-
-/* stop signal generated from keyboard */
-#ifndef SIGTSTP
-#define SIGTSTP 18
-#endif
-
-/* continue after stop */
-#ifndef SIGCONT
-#define SIGCONT 19
-#endif
-
-/* child status has changed */
-#ifndef SIGCHLD
-#define SIGCHLD 20
-#endif
-
-/* background read attempted from control terminal */
-#ifndef SIGTTIN
-#define SIGTTIN 21
-#endif
-
-/* background write attempted to control terminal */
-#ifndef SIGTTOU
-#define SIGTTOU 22
-#endif
-
-/* I/O is possible on a descriptor see fcntl(2)) */
-#ifndef SIGIO
-#define SIGIO 23
-#endif
-
-/* cpu time limit exceeded (see setrlimit(2)) */
-#ifndef SIGXCPU
-#define SIGXCPU 24
-#endif
-
-/* file size limit exceeded (see setrlimit(2)) */
-#ifndef SIGXFSZ
-#define SIGXFSZ 25
-#endif
-
-/* virtual time alarm (see setitimer(2)) */
-#ifndef SIGVTALRM
-#define SIGVTALRM 26
-#endif
-
-/* profiling timer alarm (see setitimer(2)) */
-#ifndef SIGPROF
-#define SIGPROF 27
-#endif
-
-/* window size change */
-#ifndef SIGWINCH
-#define SIGWINCH 28
-#endif
-
-/* user defined signal 1 */
-#ifndef SIGUSR1
-#define SIGUSR1 30
-#endif
-
-/* user defined signal 2 */
-#ifndef SIGUSR2
-#define SIGUSR2 31
-#endif
-
-
-int
-is_an_unhandled_exception(DWORD exit_code);
-
-/*
- *return a non-zero value if status was returned for a child process that terminated normally.
- */
-#define WIFEXITED(__status) !is_an_unhandled_exception((__status))
-
-/* if the value of WIFEXITED(__status) is non-zero, this macro evaluates the value the child
- * process returned from main().
- */
-#define WEXITSTATUS(__status) (__status)
-
-/* return a non-zero value if status was returned for a child process that terminated due to the
- * receipt of a signal that was not caught
- */
-#define WIFSIGNALED(__status) is_an_unhandled_exception((__status))
-
-/* if the value of WIFSIGNALED(__status) is non-zero, this macro evaluates to the number of the
- * signal that caused the termination of the child process.
- */
-#define WTERMSIG(__status) (__status)
-
-#endif /* WIN32 */
-
-
-#ifdef WIN32
-const char*
-signal_name(DWORD got, char* expected);
-#else
-const char*
-signal_name(unsigned int got, char *expected);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__SIGNAL_H */
+++ /dev/null
-#ifndef __ALLOCATOR_H
-#define __ALLOCATOR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef __FN_FINALIZE_T_DEFINED
-typedef int (*fn_finalize_t)(void**);
-#define __FN_FINALIZE_T_DEFINED
-#endif
-
-#ifndef __BYTE_T_DEFINED
-typedef unsigned char byte;
-#define __BYTE_T_DEFINED
-#endif
-
-/* forward declarations */
-struct s_allocator; /* allocator struct */
-struct s_allocator_block; /* allocator block struct */
-struct s_allocator_node; /* allocator node struct */
-
-
-/* the allocator node type */
-typedef struct s_allocator_node
-{
- struct s_allocator_node* next; /* the next node in the block */
- struct s_allocator_block* block; /* the block which contains the node */
- int is_allocated; /* if 1 the node is allocated (used) */
-}s_allocator_node_t,* allocator_node_t;
-
-/* the allocator block type */
-typedef struct s_allocator_block
-{
- struct s_allocator* allocator; /* the allocator which contains the block */
- struct s_allocator_block* next; /* the next block */
-}s_allocator_block_t,* allocator_block_t;
-
-/* the allocator type */
-typedef struct s_allocator
-{
- allocator_block_t head; /* the head of the allocator blocks */
- unsigned int block_capacity; /* the capacity of the allocator blocks (nodes per block) */
- int capacity; /* the current capacity of the allocator (nodes per block x block count)*/
- int type_size; /* size of allocated type */
- int size; /* current node (object) count */
- allocator_node_t free; /* pointer to the next free node */
- allocator_node_t first; /* pointer to the first free node */
- fn_finalize_t fn_finalize; /* pointer to the function used to destroy the allocated objects */
-}s_allocator_t,* allocator_t;
-
-allocator_t
-allocator_new(int block_capacity, int type_size, fn_finalize_t fn_finalize);
-
-int
-allocator_free(allocator_t* allocator_ptr);
-
-void*
-allocator_alloc(allocator_t allocator);
-
-int
-allocator_dealloc(allocator_t allocator,void* block);
-
-int
-allocator_get_size(allocator_t allocator);
-
-int
-allocator_get_capacity(allocator_t allocator);
-
-int
-allocator_get_type_size(allocator_t allocator);
-
-int
-allocator_get_block_capacity(allocator_t allocator);
-
-int
-allocator_clear(allocator_t allocator);
-
-int
-allocator_get_capacity_available(allocator_t allocator);
-
-int
-allocator_is_empty(allocator_t allocator);
-
-int
-allocator_is_full(allocator_t allocator);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__allocator_H */
+++ /dev/null
-#ifndef __GLOBAL_H
-#define __GLOBAL_H
-
-#include <types.h>
-
-#include <ctype.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * if 1, keep going when some commands can't be founded
- */
-extern int
-want_keep_going;
-
-/* if 1, ignore failures from commands
- * the possibles failures are :
- *
- * - exit code != expected exit code
- * - signal != expected signal
- * - output != expected output
- * - read pipe broken
- * - write pipe broken
- * - timeout
- *
- * remark :
- *
- * a command not found is not a failure, it's an error
- * to keep going when a command is not found specify the
- * option --keep-going
- */
-extern int
-want_keep_going_unit;
-
-/*
- * the semaphore used to synchronize the jobs
- */
-extern xbt_os_sem_t
-jobs_sem;
-
-/*
- * the semaphore used by the runner to wait the end of all the units
- */
-extern xbt_os_sem_t
-units_sem;
-
-/* the dlist of tesh include directories */
-extern vector_t
-include_dirs;
-
-extern int
-interrupted;
-
-/*extern int
-exit_code;
-*/
-
-extern int
-want_silent;
-
-extern int
-want_dry_run;
-
-extern int
-want_just_display;
-
-extern int
-dont_want_display_directory;
-
-extern directory_t
-root_directory;
-
-extern int
-want_detail_summary;
-
-extern int
-exit_code;
-
-extern pid_t
-pid;
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__GLOBAL_H */
-
+++ /dev/null
-#ifndef __COMMAND_H
-#define __COMMAND_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-command_t
-command_new(unit_t unit, context_t context, xbt_os_mutex_t mutex);
-
-void
-command_free(command_t* command);
-
-void
-command_run(command_t command);
-
-void
-command_exec(command_t command, const char* command_line);
-
-void
-command_wait(command_t command);
-
-void
-command_interrupt(command_t command);
-
-void
-command_display_status(command_t command);
-
-void
-command_handle_failure(command_t command, cs_reason_t reason);
-
-void command_kill(command_t command);
-
-void
-command_check(command_t command);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_COMMAND_H */
+++ /dev/null
-#ifndef _CONTEXT_H
-#define _CONTEXT_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-context_t
-context_new(void);
-
-void
-context_clear(context_t context);
-
-void
-context_reset(context_t context);
-
-void
-context_input_write(context_t context, const char* buffer);
-
-void
-context_ouput_read(context_t context, const char* buffer);
-
-
-
-context_t
-context_dup(context_t context);
-
-void
-context_free(context_t* context);
-
-#ifdef __cplusplus
-extern }
-#endif
-
-#endif /* !_CONTEXT_H */
+++ /dev/null
-#ifndef __DEF_H
-#define __DEF_H
-
-/* must be defined first */
-#ifdef WIN32
-
- #define _WIN32_WINNT 0x0400
-
- #if (_MSC_VER >= 1400 && !defined(_CRT_SECURE_NO_DEPRECATE))
- #define _CRT_SECURE_NO_DEPRECATE
- #endif
-
- #include <direct.h> /* for getcwd(), _chdir() */
-
-#endif
-
-
-#include <error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef WIN32
-
- #define strdup _strdup
- #define chdir _chdir
- #define getcwd _getcwd
-
- #ifndef S_ISDIR
- #define S_ISDIR(__mode) (((__mode) & S_IFMT) == S_IFDIR)
- #endif
-
- #ifndef S_ISREG
- #define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG)
- #endif
-
- #define INDEFINITE_PID NULL
- #define INDEFINITE_FD NULL
-#else
- #define INDEFINITE_PID ((int)-1)
- #define INDEFINITE_FD ((int)-1)
-#endif
-
-#ifndef MAX_PATH
- #define MAX_PATH ((unsigned int)255)
-#endif
-
-
-#define INDEFINITE ((int)-1)
-#define INDEFINITE_SIGNAL NULL
-
-#define DEFAULT_FSTREAMS_CAPACITY ((int)128)
-#define DEFAULT_INCLUDE_DIRS_CAPACITY DEFAULT_FSTREAMS_CAPACITY
-#define DEFAULT_UNITS_CAPACITY ((int)64)
-#define DEFAULT_INCLUDES ((int)8)
-#define DEFAULT_COMMANDS_CAPACITY ((int)512)
-#define DEFAULT_SUITES_CAPACITY ((int)32)
-
-#define MAX_SUFFIX ((unsigned int)9)
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__DEF_H */
-
+++ /dev/null
-#ifndef __dictionary_H
-#define __dictionary_H
-
-#include <htable.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __FN_FINALIZE_T_DEFINED
-typedef int (*fn_finalize_t)(void**);
-#define __FN_FINALIZE_T_DEFINED
-#endif
-
-typedef struct s_dictionary
-{
- htable_t htable;
-}s_dictionary_t,* dictionary_t;
-
-
-dictionary_t
-dictionary_new(fn_finalize_t fn_finalize);
-
-int
-dictionary_set(dictionary_t dictionary,const char* key, const void* val);
-
-void*
-dictionary_get(dictionary_t dictionary,const char* key);
-
-int
-dictionary_free(dictionary_t* dictionaryptr);
-
-int
-dictionary_clear(dictionary_t dictionary);
-
-int
-dictionary_get_size(dictionary_t dictionary);
-
-int
-dictionary_is_empty(dictionary_t dictionary);
-
-void*
-dictionary_remove(dictionary_t dictionary,const char* key);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__dictionary_H */
+++ /dev/null
-#ifndef __DIRECTORIES_H
-#define __DIRECTORIES_H
-
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-directories_t
-directories_new(void);
-
-int
-directories_add(directories_t directories, directory_t directory);
-
-int
-directories_contains(directories_t directories, directory_t directory);
-
-int
-directories_load(directories_t directories, fstreams_t fstreams, lstrings_t suffixes);
-
-int
-directories_free(void** directoriesptr);
-
-/*directory_t
-directories_get_back(directories_t directories);*/
-
-
-int
-directories_get_size(directories_t directories);
-
-int
-directories_is_empty(directories_t directories);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*!__DIRECTORIES_H */
+++ /dev/null
-#ifndef __DIRECTORY_H
-#define __DIRECTORY_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-directory_t
-directory_new(const char* name);
-
-int
-directory_open(directory_t directory);
-
-int
-directory_close(directory_t directory);
-
-int
-directory_load(directory_t directory, fstreams_t fstreams, lstrings_t suffixes);
-
-int
-directory_free(void** directoryptr);
-
-const char*
-directory_get_name(directory_t directory);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*!__DIRECTORY_H */
+++ /dev/null
-#ifndef __ERROR_H
-#define __ERROR_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <errno.h>
-
-#define EREAD ((int)100) /* a read pipe operation failed */
-#define EREADPIPE ((int)101) /* the pipe used to read from the stdout of the command is broken */
-#define ETIMEOUT ((int)102) /* the command is timeouted */
-#define EWRITE ((int)103) /* a write operation failed */
-#define EWRITEPIPE ((int)104) /* the pipe used to write to the stdin of the command is broken */
-#define EEXEC ((int)105) /* can't execute the command */
-#define EWAIT ((int)106) /* the wait function failed */
-#define ECMDNOTFOUND ((int)107) /* the command is not found */
-#define EEXITCODENOTMATCH ((int)108) /* the exit codes don't match */
-#define EOUTPUTNOTMATCH ((int)109) /* the outputs don't match */
-#define ESIGNOTMATCH ((int)110) /* the signals don't match */
-#define EUNEXPECTEDSIG ((int)111) /* unexpected signal caught */
-#define ESIGNOTRECEIPT ((int)112) /* the expected signal is not receipt */
-#define EFILENOTFOUND ((int)113) /* the specified tesh file is not found */
-#define EGETCWD ((int)114) /* this is a system error : the getcwd() function failed (impossible) */
-#define EDIRNOTFOUND ((int)115) /* the specified directory is not found */
-#define ECHDIR ((int)116) /* this is a system error : the chdir() function failed (impossible) */
-#define EPROCCMDLINE ((int)117) /* this is an internal error : the process_command_line() function failed */
-#define ENOARG ((int)118) /* a none optional argument is not specified in the command line */
-#define ENOTPOSITIVENUM ((int)119) /* the argument of the option is not strictly positive */
-#define ESYNTAX ((int)120) /* syntax error */
-#define EINVALIDTIMEOUT ((int)121) /* the timeout value specified by the metacommand is invalid */
-#define EINVALIDEXITCODE ((int)122) /* the expected exit code value specified by the metacommand is invalid */
-#define ESIGNOTSUPP ((int)123) /* the signal specified by the metacommand is not supported */
-#define ELEADTIME ((int)124) /* global timeout */
-#define EREADMENOTFOUND ((int)125) /* unable to locate the README.txt file */
-#define EINCLUDENOTFOUND ((int)126) /* the include file specified by a metacommand is not found */
-#define ESUFFIXTOOLONG ((int)127) /* the suffix is too long */
-#define EFILENOTINSPECDIR ((int)128) /* file not found in the specified directories */
-#define EFILENOTINCURDIR ((int)129) /* file not found in the current directory */
-
-
-const char*
-error_get_at(int pos, int* code);
-
-const char*
-error_to_string(int errcode);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__ERROR_H */
-
+++ /dev/null
-#ifndef __EXCLUDES_H
-#define __EXCLUDES_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-excludes_t
-excludes_new(void);
-
-int
-excludes_add(excludes_t excludes, fstream_t fstream);
-
-int
-excludes_contains(excludes_t excludes, fstream_t fstream);
-
-int
-excludes_is_empty(excludes_t excludes);
-
-int
-excludes_check(excludes_t excludes, fstreams_t fstreams);
-
-int
-excludes_free(void** excludesptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*!__EXCLUDES_H */
+++ /dev/null
-#ifndef __FSTREAM_H
-#define __FSTREAM_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-fstream_t
-fstream_new(const char* directory, const char* name);
-
-int
-fstream_open(fstream_t fstream);
-
-int
-fstream_close(fstream_t fstream);
-
-int
-fstream_free(void** fstreamptr);
-
-void
-fstream_parse(fstream_t fstream, unit_t unit, xbt_os_mutex_t mutex);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*! __FSTREAM_H */
+++ /dev/null
-#ifndef __FSTREAMS_H
-#define __FSTREAMS_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-fstreams_t
-fstreams_new(int capacity, fn_finalize_t fn_finalize);
-
-int
-fstreams_exclude(fstreams_t fstreams, excludes_t excludes);
-
-int
-fstreams_contains(fstreams_t fstreams, fstream_t fstream);
-
-int
-fstreams_add(fstreams_t fstreams, fstream_t fstream);
-
-int
-fstreams_free(void** fstreamsptr);
-
-int
-fstreams_get_size(fstreams_t fstreams);
-
-int
-fstreams_is_empty(fstreams_t fstreams);
-
-int
-fstreams_contains(fstreams_t fstreams, fstream_t fstream);
-
-int
-fstreams_load(fstreams_t fstreams);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__FSTREAMS_H */
+++ /dev/null
-#ifndef __GETPATH_H
-#define __GETPATH_H
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* getpath th -- get the path of the file name specified by the first parameter
- * of the function and store the path in its second parmater.
- * the function returns the length of the path of the file.
- *
- * param file_name The file name to get the path
- * param path The address of the path of the file
- *
- * return If successful, the function returns the len of the path.
- * Otherwise the function returns -1 and sets errno to indicate
- * the error.
- *
- * errors
- *
- * [ENOENT] the file name specified as parameter does not exist.
- *
- * [ENOMEM] because this function use calloc, errno can be set with
- * this error code.
- *
- */
-int
-getpath(const char* file_name, char** path);
-
-/* translatepath -- path translation
- *
- * param totranslate The path to translate.
- * param transled The address of the translated path.
- *
- * return If successful the function returns the len of the translated path.
- * 0therwise the function returns -1 and sets the global variable errno
- * to indicate the error.
- *
- * errors [ENOTDIR] the path to translate is not a directory.
-
- * [ENOMEM] because this function use calloc, errno can be set with
- * this error code.
- */
-int
-translatepath(const char* totranslate, char** translated);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__GETPATH_H */
+++ /dev/null
-#ifndef __GLOBAL_H
-#define __GLOBAL_H
-
-#include <types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * if 1, keep going when some commands can't be founded
- */
-extern int
-want_keep_going;
-
-/* if 1, ignore failures from commands
- * the possibles failures are :
- *
- * - exit code != expected exit code
- * - signal != expected signal
- * - output != expected output
- * - read pipe broken
- * - write pipe broken
- * - timeout
- *
- * remark :
- *
- * a command not found is not a failure, it's an error
- * to keep going when a command is not found specify the
- * option --keep-going
- */
-extern int
-want_keep_going_unit;
-
-/*
- * the semaphore used to synchronize the jobs
- */
-extern xbt_os_sem_t
-jobs_sem;
-
-/*
- * the semaphore used by the runner to wait the end of all the units
- */
-extern xbt_os_sem_t
-units_sem;
-
-/* the dlist of tesh include directories */
-extern vector_t
-include_dirs;
-
-extern int
-interrupted;
-
-extern int
-exit_code;
-
-extern int
-want_silent;
-
-extern int
-want_dry_run;
-
-extern int
-want_just_display;
-
-extern int
-dont_want_display_directory;
-
-extern directory_t
-root_directory;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__GLOBAL_H */
-
+++ /dev/null
-#ifndef __HTABLE
-#define __HTABLE
-
-
-#include <allocator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __FN_FINALIZE_T_DEFINED
-typedef int (*fn_finalize_t)(void**);
-#define __FN_FINALIZE_T_DEFINED
-#endif
-
-
-/*
- * pointer to a compare key function.
- * the function takes two items to compare and returns true if they are equal.
- */
-#ifndef __FN_CMP_KEY_T_DEFINED
-typedef int (*fn_cmp_key_t)(const void*, const void*);
-#define __FN_CMP_KEY_T_DEFINED
-#endif
-
-/*
- * pointer to a hash function.
- * the function take the value to compute the hash value that it returns.
- */
-#ifndef __FN_HFUNC_T_DEFINED
-typedef unsigned int (*fn_hfunc_t)(const void*);
-#define __FN_HFUNC_T_DEFINED
-#endif
-
-typedef struct s_hassoc
-{
- struct s_hassoc* next;
- const void* key;
- const void* val;
-}s_hassoc_t,* hassoc_t;
-
-typedef struct s_htable
-{
- hassoc_t* content; /* the hache table content */
- int size; /* the size of the hash table */
- allocator_t allocator; /* the allocator used to allocate the associations */
- fn_hfunc_t fn_hfunc; /* a pointer to the hash function to use */
- fn_cmp_key_t fn_cmp_key; /* a pointer to the function used to fn_cmp_key the key */
- fn_finalize_t fn_finalize;
-}s_htable_t,* htable_t;
-
-
-
-
-
-htable_t
-htable_new(
- int block_capacity, /* the block capacity of the blocks of the allocator used by the htable */
- int size, /* the size of the table size */
- fn_hfunc_t fn_hfunc, /* the pointer to the function to use */
- fn_cmp_key_t fn_cmp_key, /* the pointer to the function used to fn_cmp_key the keys of the assocs */
- fn_finalize_t fn_finalize /* the pointer to the function used to destroy the values of the assocs */
- );
-
-int
-htable_set(htable_t htable, const void* key, const void* val);
-
-void*
-htable_lookup(htable_t htable, const void* key);
-
-void*
-htable_remove(htable_t htable, const void* key);
-
-int
-htable_erase(htable_t htable, const void* key);
-
-int
-htable_free(htable_t* htableptr);
-
-int
-htable_clear(htable_t htable);
-
-int
-htable_get_size(htable_t htable);
-
-int
-htable_is_empty(htable_t htable);
-
-int
-htable_is_autodelete(htable_t htable);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__HTABLE */
-
+++ /dev/null
-#ifndef __list_H
-#define __list_H
-
-#include <allocator.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __FN_FINALIZE_T_DEFINED
-typedef int (*fn_finalize_t)(void**);
-#define __FN_FINALIZE_T_DEFINED
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef __LINK_T_DEFINED
-typedef struct s_link_t
-{
- void* item; /* the item associated with the link */
- struct s_link_t* next; /* address to the next link */
- struct s_link_t* prev; /* address to the prev link */
-}s_link_t,* link_t;
-#define __LINK_T_DEFINED
-#endif
-
-typedef struct s_list
-{
- void* item; /* not used */
- link_t next; /* point to the last node of the list */
- link_t prev; /* point to the first node of the list */
- fn_finalize_t fn_finalize; /* not used */
- int size; /* the number of node contained by the list */
- link_t cur;
- int pos;
-}s_list_t,* list_t;
-
-list_t
-list_new(fn_finalize_t fn_finalize);
-
-int
-list_rewind(list_t list);
-
-int
-list_unwind(list_t list);
-
-int
-list_clear(list_t list);
-
-int
-list_free(list_t* list_ptr);
-
-int
-list_push_front(list_t list, void* item);
-
-int
-list_push_back(list_t list, void* item);
-
-void*
-list_pop_back(list_t list);
-
-void*
-list_pop_front(list_t list);
-
-int
-list_remove(list_t list, void* item);
-
-int
-list_get_size(list_t list);
-int
-list_contains(list_t list, void* item);
-
-int
-list_is_empty(list_t list);
-
-int
-list_is_autodelete(list_t list);
-
-int
-list_move_next(list_t list);
-
-void*
-list_get(list_t list);
-
-void*
-list_set(list_t list, void* item);
-
-void*
-list_get_at(list_t list, int pos);
-
-void*
-list_set_at(list_t list, int pos, void* item);
-
-int
-list_move_prev(list_t list);
-
-int
-list_seek(list_t list, int offset, int whence);
-
-int
-list_tell(list_t list);
-
-int
-list_getpos(list_t list, int* pos);
-
-int
-list_setpos(list_t list, int pos);
-
-
-void*
-list_get_front(list_t list);
-
-void*
-list_get_back(list_t list);
-
-int
-list_insert_after(list_t list, void* what, void* where);
-
-int
-list_insert_before(list_t list, void* what, void* where);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__list_H */
+++ /dev/null
-#ifndef __lstrings_H
-#define __lstrings_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef __LINK_T_DEFINED
-typedef struct s_link_t
-{
- void* item; /* the item associated with the link */
- struct s_link_t* next; /* address to the next link */
- struct s_link_t* prev; /* address to the prev link */
-}s_link_t,* link_t;
-#define __LINK_T_DEFINED
-#endif
-
-typedef struct s_lstrings
-{
- const char* item; /* not used */
- link_t next; /* point to the last node of the lstrings */
- link_t prev; /* point to the first node of the lstrings */
- int size; /* the number of node contained by the lstrings */
- link_t cur;
- int pos;
-}s_lstrings_t,* lstrings_t;
-
-lstrings_t
-lstrings_new(void);
-
-int
-lstrings_rewind(lstrings_t lstrings);
-
-int
-lstrings_unwind(lstrings_t lstrings);
-
-int
-lstrings_clear(lstrings_t lstrings);
-
-int
-lstrings_free(lstrings_t* lstrings_ptr);
-
-int
-lstrings_push_front(lstrings_t lstrings, const char* string);
-
-int
-lstrings_push_back(lstrings_t lstrings, const char* string);
-
-const char*
-lstrings_pop_back(lstrings_t lstrings);
-
-const char*
-lstrings_pop_front(lstrings_t lstrings);
-
-int
-lstrings_remove(lstrings_t lstrings, const char* string);
-
-int
-lstrings_get_size(lstrings_t lstrings);
-int
-lstrings_contains(lstrings_t lstrings, const char* string);
-
-int
-lstrings_is_empty(lstrings_t lstrings);
-
-int
-lstrings_move_next(lstrings_t lstrings);
-
-const char*
-lstrings_get(lstrings_t lstrings);
-
-const char*
-lstrings_set(lstrings_t lstrings, const char* string);
-
-const char*
-lstrings_get_at(lstrings_t lstrings, int pos);
-
-const char*
-lstrings_set_at(lstrings_t lstrings, int pos, const char* string);
-
-int
-lstrings_move_prev(lstrings_t lstrings);
-
-int
-lstrings_seek(lstrings_t lstrings, int offset, int whence);
-
-int
-lstrings_tell(lstrings_t lstrings);
-
-int
-lstrings_getpos(lstrings_t lstrings, int* pos);
-
-int
-lstrings_setpos(lstrings_t lstrings, int pos);
-
-const char*
-lstrings_get_front(lstrings_t lstrings);
-
-const char*
-lstrings_get_back(lstrings_t lstrings);
-
-int
-lstrings_insert_after(lstrings_t lstrings, const char* what, const char* where);
-
-int
-lstrings_insert_before(lstrings_t lstrings, const char* what, const char* where);
-
-char**
-lstrings_to_cstr(lstrings_t lstrings);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__lstrings_H */
+++ /dev/null
-#ifndef __READER_H
-#define __READER_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-reader_t
-reader_new(command_t command);
-
-void
-reader_free(reader_t* reader);
-
-void
-reader_read(reader_t reader);
-
-void
-reader_wait(reader_t reader);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__READER_H */
+++ /dev/null
-#ifndef __RUNNER_H
-#define __RUNNER_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int
-runner_init(int want_check_syntax, int timeout, fstreams_t fstreams);
-
-void
-runner_destroy(void);
-
-void
-runner_run(void);
-
-void
-runner_display_status(void);
-
-void
-runner_interrupt(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__RUNNER_H */
+++ /dev/null
-#ifndef __STR_REPLACE_H
-#define __STR_REPLACE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int
-str_replace(char** str, const char *what, const char *with);
-
-int
-str_replace_all(char** str, const char* what, const char* with);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__STR_REPLACE_H */
+++ /dev/null
-#ifndef __SUITE_H
-#define __SUITE_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-suite_t
-suite_new(unit_t owner, const char* description);
-
-void
-suite_include_unit(suite_t suite, unit_t unit);
-
-void
-suite_free(suite_t* suite);
-
-#ifdef __cplusplus
-extern }
-#endif
-
-
-#endif /* !__SUITE_H */
-
+++ /dev/null
-#ifndef __TIMER_H
-#define __TIMER_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-ttimer_t
-timer_new(command_t command);
-
-void
-timer_free(ttimer_t* timer);
-
-void
-timer_time(ttimer_t timer);
-
-void
-timer_wait(ttimer_t timer);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__TIMER_H */
+++ /dev/null
-#ifndef __TYPES_H
-#define __TYPES_H
-
-#include <def.h>
-
-#include <portable.h>
-#include <xbt/xbt_os_thread.h>
-#include <xbt/strbuff.h>
-#include <xbt.h>
-
-#include <dirent.h>
-
-#include <lstrings.h>
-#include <vector.h>
-#include <dictionary.h>
-
-#ifdef _cplusplus
-extern "C" {
-#endif
-
-/*
- * byte type definition
- */
-#ifndef __BYTE_T_DEFINED
- typedef unsigned char byte;
- #define __BYTE_T_DEFINED
-#endif
-
-/*
- * file descriptor and pid types for portability.
- */
-
-#ifdef WIN32
-
- #ifndef __FD_T_DEFINED
- typedef HANDLE fd_t;
- #define __FD_T_DEFINED
- #endif
-
- #ifndef __PID_T_DEFINED
- typedef HANDLE pid_t;
- #define __PID_T_DEFINED
- #endif
-
-#else
-
- #ifndef __FD_T_DEFINED
- typedef int fd_t;
- #define __FD_T_DEFINED
- #endif
-
- #ifndef __PID_T_DEFINED
- typedef int pid_t;
- #define __PID_T_DEFINED
- #endif
-#endif
-
-
-/* forward declarations */
-struct s_runner;
-struct s_units;
-struct s_unit;
-struct s_suites;
-struct s_suite;
-struct s_excludes;
-struct s_fstreams;
-struct s_fstream;
-struct s_directories;
-struct s_directory;
-struct s_writer;
-struct s_reader;
-struct s_timer;
-struct s_context;
-struct s_command;
-struct s_variable;
-struct s_variables;
-
-
-
-/*
- * command status
- */
-typedef enum e_command_status
-{
- cs_initialized = 0, /* the is initialized */
- cs_started = 1, /* the command is started */
- cs_in_progress = 2, /* the command is execited */
- cs_waiting = 3, /* the command is waiting the writer, the reader and the timer */
- cs_interrupted = 4, /* the command is interrupted */
- cs_failed = 5, /* the command is failed */
- cs_successeded = 6, /* the command is successeded */
- cs_killed = 7 /* the command is killed */
-}command_status_t;
-
-/*
- * reason of the status of the command
- */
-typedef enum e_command_status_raison
-{
- csr_unknown = 0, /* unknown reason */
- csr_read_failure = 1, /* a read operation failed */
- csr_read_pipe_broken = 2, /* the pipe used to read from the stdout of the command is broken */
- csr_timeout = 3, /* timeout */
- csr_write_failure = 4, /* a write operation failed */
- csr_write_pipe_broken = 5, /* the pipe used to write to the stdin of the command is broken */
- csr_exec_failure = 6, /* can't execute the command */
- csr_wait_failure = 8, /* the wait process function failed */
- csr_interruption_request = 9, /* the command has received an interruption request */
- csr_command_not_found = 10, /* the command is not found */
- csr_exit_codes_dont_match = 11,
- csr_outputs_dont_match = 12,
- csr_signals_dont_match = 13,
- csr_unexpected_signal_caught = 14,
- csr_expected_signal_not_receipt = 15,
- csr_pipe_function_failed = 16 /* the function pipe() or CreatePipe() fails */
-}cs_reason_t;
-
-typedef struct s_variable
-{
- char* name;
- char* val;
- int used:1;
- int env:1;
- int err:1;
-}s_variable_t,* variable_t;
-
-typedef struct s_variables
-{
- dictionary_t items;
-}s_variables_t,* variables_t;
-
-/*
- * declaration of the tesh timer type
- */
-typedef struct s_timer
-{
- xbt_os_thread_t thread; /* asynchronous timer */
- struct s_command* command; /* the timed command */
- int timeouted; /* if 1, the timer is timeouted */
- xbt_os_sem_t started;
-}s_timer_t,* ttimer_t;
-
-/*
- * declaration of the tesh reader type
- */
-typedef struct s_reader
-{
- xbt_os_thread_t thread; /* asynchonous reader */
- struct s_command* command; /* the command of the reader */
- int failed; /* if 1, the reader failed */
- int broken_pipe; /* if 1, the pipe used by the reader is broken */
- int done;
- xbt_os_sem_t started;
-}s_reader_t,* reader_t;
-
-/*
- * declaration of the tesh writer type
- */
-typedef struct s_writer
-{
- xbt_os_thread_t thread; /* asynchronous writer */
- struct s_command* command; /* the command of the writer */
- int failed; /* if 1, the writer failed */
- int broken_pipe; /* if 1, the pipe used by the writer is broken */
- xbt_os_sem_t written;
- xbt_os_sem_t can_write;
- int done;
-}s_writer_t,* writer_t;
-
-
-typedef struct s_units
-{
- vector_t items; /* used to store the units */
- int number_of_runned_units; /* the number of units runned */
- int number_of_ended_units; /* the number of units over */
-
-}s_units_t,* units_t;
-
-/*
- * declaration of the tesh unit type
- */
-typedef struct s_unit
-{
- char* description;
- int is_suite;
- struct s_fstream* fstream;
- struct s_runner* runner; /* the runner of the unit */
- vector_t commands;
- int number_of_commands; /* number of created commands of the unit */
- int number_of_started_commands; /* number of runned commands of the unit */
- int number_of_interrupted_commands; /* number of interrupted commands of the unit */
- int number_of_failed_commands; /* number of failed commands of the unit */
- int number_of_successeded_commands; /* number of successeded commands of the unit */
- int number_of_terminated_commands; /* number of ended commands */
- int number_of_waiting_commands;
- xbt_os_thread_t thread; /* all the units run in its own thread */
- xbt_os_sem_t sem; /* used by the commands of the unit to signal the end of the unit */
- xbt_os_mutex_t mutex; /* used to synchronously access to the properties of the runner */
- int interrupted; /* if 1, the unit is interrupted by the runner */
- int failed; /* if 1, the unit is failed */
- int successeded; /* if 1, the unit is successeded */
- int parsed; /* if 1, the tesh file of the unit is parsed */
- int released;
- int parsing_include_file;
- struct s_unit* owner; /* the unit containing the unit if any */
- struct s_unit* root;
- vector_t suites;
- int number; /* the number of suites */
- int capacity; /* the number of suites that the unit can contain */
- int running_suite; /* if 1, the suite running a suite */
- vector_t includes;
-}s_unit_t,* unit_t;
-
-
-
-
-/*
- * declaration of tesh suite type
- */
-typedef struct s_suite
-{
- const char* description; /* the name of the suite */
- struct s_unit* owner; /* the unit owning the suite */
- vector_t units; /* the units of the suite */
- int number; /* the numnber of suites contained by the suite */
- int capacity; /* the number of suites that the vector can contain */
- int number_of_successed_units; /* the number of successeded units of the suite */
- int number_of_failed_units; /* the number of failed units of the suite */
-}s_suite_t,* suite_t;
-
-/*
- * declaration of the tesh runner type
- */
-typedef struct s_runner
-{
-
- /*vector_t units;*/ /* the vector containing all the units launched by the runner */
- struct s_units* units;
- int timeouted; /* if 1, the runner is timeouted */
- int timeout; /* the timeout of the runner */
- int interrupted; /* if 1, the runner failed */
- int number_of_runned_units; /* the number of units runned by the runner */
- int number_of_ended_units; /* the number of ended units */
- int waiting; /* if 1, the runner is waiting the end of all the units */
- xbt_os_thread_t thread; /* the timer thread */
- vector_t variables;
-
- int total_of_tests;
- int total_of_successeded_tests;
- int total_of_failed_tests;
- int total_of_interrupted_tests;
-
- int total_of_units;
- int total_of_successeded_units;
- int total_of_failed_units;
- int total_of_interrupted_units;
-
- int total_of_suites;
- int total_of_successeded_suites;
- int total_of_failed_suites;
- int total_of_interrupted_suites;
-}s_runner_t,* runner_t;
-
-
-typedef struct s_fstreams
-{
- vector_t items;
-}s_fstreams_t,* fstreams_t;
-
-
-typedef struct s_fstream
-{
- char* name;
- char* directory;
- FILE* stream;
-}s_fstream_t,* fstream_t;
-
-typedef struct s_excludes
-{
- vector_t items;
-}s_excludes_t,* excludes_t;
-
-typedef struct s_directory
-{
- char* name;
- DIR* stream;
-}s_directory_t,* directory_t;
-
-typedef struct s_directories
-{
- vector_t items;
-}s_directories_t,* directories_t;
-
-
-typedef enum
-{
- oh_check,
- oh_display,
- oh_ignore
-}output_handling_t;
-/*
- * declaration of the tesh context type
- */
-typedef struct s_context
-{
- const char* command_line; /* the command line of the command to execute */
- const char* line; /* the current parsed line */
- int exit_code; /* the expected exit code of the command */
- char* signal; /* the expected signal raised by the command */
- int timeout; /* the timeout of the test */
- xbt_strbuff_t input; /* the input to write in the stdin of the command to run */
- xbt_strbuff_t output; /* the expected output of the command of the test */
- output_handling_t output_handling;
- int async; /* if 1, the command is asynchronous */
-}s_context_t,* context_t;
-
-
-typedef void (*fn_sig_io_handler_t)(int);
-/*
- * declaration of the tesh command type
- */
-typedef struct s_command
-{
- unit_t unit; /* the unit of the command */
- struct s_context* context; /* the context of the execution of the command */
- xbt_os_thread_t thread; /* asynchronous command */
- struct s_writer* writer; /* the writer used to write in the command stdin */
- struct s_reader* reader; /* the reader used to read from the command stout */
- struct s_timer* timer; /* the timer used for the command */
- command_status_t status; /* the current status of the command */
- cs_reason_t reason; /* the reason of the state of the command */
- int successeded; /* if 1, the command is successeded */
- int interrupted; /* if 1, the command is interrupted */
- int failed; /* if 1, the command is failed */
- pid_t pid; /* the program id of the command */
- xbt_strbuff_t output; /* the output of the command */
- fd_t stdout_fd; /* the stdout fd of the command */
- fd_t stdin_fd; /* the stdin fd of the command */
- int exit_code; /* the exit code of the command */
- #ifdef WIN32
- unsigned long stat_val;
- #else
- int stat_val;
- #endif
- char* signal; /* the signal raised by the command if any */
- xbt_os_mutex_t mutex;
- #ifndef WIN32
- int killed; /* if 1, the command was killed */
- #endif
-
- fn_sig_io_handler_t fn_sig_io_handler;
-}s_command_t,* command_t;
-
-#ifdef _cplusplus
-}
-#endif
-
-
-#endif /* !__TYPES_H */
+++ /dev/null
-#ifndef __UNIT_H
-#define __UNIT_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-unit_t
-unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream);
-
-int
-unit_free(void** unitptr);
-
-
-int
-unit_reset(unit_t unit);
-
-void
-unit_run(unit_t unit, xbt_os_mutex_t mutex);
-
-void
-unit_interrupt(unit_t unit);
-
-void
-unit_verbose(unit_t unit);
-
-void
-unit_handle_failure(unit_t unit);
-
-void
-unit_handle_line(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char * filepos, char *line);
-
-void
-unit_pushline(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* filepos, char kind, char *line);
-
-void
-unit_handle_include(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, const char* description);
-
-void
-unit_parse(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, FILE* stream);
-
-void
-unit_handle_suite(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* description);
-
-void
-display_title(const char* description);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* !__UNIT_H */
+++ /dev/null
-#ifndef __UNITS_H
-#define __UNITS_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-units_t
-units_new(runner_t runner, fstreams_t fstreams);
-
-int
-units_is_empty(units_t unit);
-
-int
-units_get_size(units_t unit);
-
-int
-units_run_all(units_t units, xbt_os_mutex_t mutex);
-
-int
-units_join_all(units_t units);
-
-int
-units_interrupt_all(units_t units);
-
-int
-units_reset_all(units_t units);
-
-
-int
-units_verbose(units_t units);
-
-int
-units_free(void** unitsptr);
-
-
-#ifdef __cplusplus
-extern }
-#endif
-
-
-#endif /* !__UNITS_H */
-
-
+++ /dev/null
-#ifndef __VARIABLE_H
-#define __VARIABLE_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-variable_t
-variable_new(const char* name, const char* val);
-
-int
-variable_free(variable_t* variableptr);
-
-int
-variable_is_used(variable_t variable);
-
-int
-variable_set_used(variable_t variable);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*!__VARIABLE_H */
-
+++ /dev/null
-#ifndef __VARIABLES_H
-#define __VARIABLES_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-variables_t
-variables_new(void);
-
-int
-variables_free(variables_t* variablesptr);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*!__VARIABLES_H */
\ No newline at end of file
+++ /dev/null
-/**
- * File : private/vector.h
- *
- * Copyright 2006,2007 Malek Cherier, Martin Quinson. 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.
- */
-
-#ifndef __VECTOR_H
-#define __VECTOR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef __FN_FINALIZE_T_DEFINED
-typedef int (*fn_finalize_t)(void**);
-#define __FN_FINALIZE_T_DEFINED
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-/*
- * this type represents a vector of void* pointers.
- */
-typedef struct s_vector
-{
- int size; /* the number of items of the vector */
- int capacity; /* the capacity of the vector */
- void** items; /* the items of the vector */
- fn_finalize_t fn_finalize; /* a pointer to a function used to cleanup the elements of the vector */
- int pos;
-}s_vector_t,* vector_t;
-
-vector_t
-vector_new(int capacity,fn_finalize_t fn_finalize);
-
-int
-vector_clear(vector_t vector);
-
-int
-vector_free(vector_t* vector_ptr);
-
-int
-vector_is_empty(vector_t vector);
-
-void*
-vector_get_at(vector_t vector, int pos);
-
-int
-vector_get_size(vector_t vector);
-
-void*
-vector_get_front(vector_t vector);
-
-void*
-vector_get_back(vector_t vector);
-
-int
-vector_get_capacity_available(vector_t vector);
-
-int
-vector_push_back(vector_t vector, void* item);
-
-void*
-vector_pop_back(vector_t vector);
-
-int
-vector_get_upper_bound(vector_t vector);
-
-void*
-vector_set_at(vector_t vector, int index, void* item);
-
-int
-vector_insert(vector_t vector, int index, void* item);
-
-int
-vector_erase_at(vector_t vector, int index);
-
-int
-vector_erase(vector_t vector, void* item);
-
-int
-vector_erase_range(vector_t vector, int first, int last);
-
-int
-vector_remove(vector_t vector, void* item);
-
-int
-vector_search(vector_t vector, void* item);
-
-int
-vector_assign(vector_t dst,vector_t src);
-
-int
-vector_get_capacity(vector_t vector);
-
-int
-vector_equals(vector_t vector, vector_t other);
-
-int
-vector_swap(vector_t vector, vector_t other);
-
-vector_t
-vector_clone(vector_t vector);
-
-int
-vector_contains(vector_t vector,void* item);
-
-int
-vector_reserve(vector_t vector,int size);
-
-int
-vector_is_autodelete(vector_t vector);
-
-int
-vector_has_capacity_available(vector_t vector);
-
-int
-vector_is_full(vector_t vector);
-
-int
-vector_get_max_index(vector_t vector);
-
-void*
-vector_get(vector_t vector);
-
-void*
-vector_get_at(vector_t vector, int pos);
-
-int
-vector_getpos(vector_t vector, int* pos);
-
-int
-vector_move_next(vector_t vector);
-
-int
-vector_move_prev(vector_t vector);
-
-int
-vector_rewind(vector_t vector);
-
-int
-vector_seek(vector_t vector, int offset, int whence);
-
-void*
-vector_set(vector_t vector, void* item);
-
-int
-vector_setpos(vector_t vector, int pos);
-
-int
-vector_tell(vector_t vector);
-
-int
-vector_unwind(vector_t vector);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !XBT_PRIVATE_VECTOR_PTR_H */
+++ /dev/null
-#ifndef __WRITER_H
-#define __WRITER_H
-
-#include <com.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-writer_t
-writer_new(command_t command);
-
-void
-writer_free(writer_t* writer);
-
-void
-writer_write(writer_t writer);
-
-void
-writer_wait(writer_t writer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__WRITER_H */
+++ /dev/null
-PREFIX = /home/mcherier/com/loria/tesh
-INCLUDE_DIR = $(PREFIX)/include/
-SRC_DIR = $(PREFIX)/src/
-OBJECTS = main.o command.o context.o reader.o runner.o signal.o timer.o suite.o unit.o writer.o list.o lstrings.o allocator.o vector.o htable.o dictionary.o units.o directory.o directories.o fstream.o fstreams.o excludes.o error.o
-CC = gcc
-CCFLAGS = -ggdb -g -I$(INCLUDE_DIR) -I/home/mcherier/svn/simgrid/include/ -I/home/mcherier/svn/simgrid/src/ -I/home/mcherier/svn/simgrid/src/include/ -Wall -pedantic
-LDLIBS = simgrid
-
-PROG = tesh
-
-all: $(PROG)
-
-$(PROG): $(OBJECTS)
- $(CC) -o $(PROG) $(OBJECTS) -L/home/mquinson/simgrid-svn/src/.libs/ -l$(LDLIBS)
-
-%.o: $(SRC_DIR)%.c $(INCLUDE_DIR)*.h
- $(CC) -c $(CCFLAGS) $(SRC_DIR)$*.c
-
-clean:
- rm -f $(OBJECTS) $(PROG)
-
-
\ No newline at end of file
+++ /dev/null
-
-#include <allocator.h>
-
-#include <errno.h>
-#include <string.h> /* memset */
-#include <stdlib.h> /* calloc() free() */
-
-
-static int
-resize(allocator_t allocator)
-{
- allocator_node_t cur, next;
- allocator_block_t block;
- int block_capacity, type_size, node_size;
- register int pos;
-
- if(!allocator)
- return EINVAL;
-
- next = NULL;
- block_capacity = allocator->block_capacity;
- type_size = allocator->type_size;
- node_size = type_size + sizeof(s_allocator_node_t);
-
- if(!(block = (allocator_block_t)calloc(1,sizeof(s_allocator_block_t) + (block_capacity * node_size))))
- return errno;
-
- /* update the first block of the allocator */
- block->next = allocator->head;
- block->allocator = allocator;
- allocator->head = block;
-
- /* move to the last node of the block. */
- cur = (allocator_node_t)(((byte*)(block + 1)) + ((block_capacity - 1) * node_size));
-
- /* initialize all the nodes of the new block */
- for(pos = block_capacity - 1; pos >= 0; pos--, cur = (allocator_node_t)(((byte*)next) - node_size))
- {
- cur->next = next;
- cur->block = block;
- next = cur;
- }
-
- /* allocator->free pointed now on the first node of the new bloc. */
- allocator->free = allocator->first = next;
- /* update the allocator capacity. */
- allocator->capacity += block_capacity;
-
- return 0;
-}
-
-allocator_t
-allocator_new(int block_capacity, int type_size, fn_finalize_t fn_finalize)
-{
- allocator_t allocator;
-
- if((block_capacity <= 0) || (type_size <= 0))
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(allocator = (allocator_t)calloc(1,sizeof(s_allocator_t))))
- return NULL;
-
- /* updates allocator properties */
- allocator->block_capacity = block_capacity;
- allocator->type_size = type_size;
-
- /* first block allocation */
-
- if(resize(allocator))
- {
- free(allocator);
- return NULL;
- }
-
- allocator->fn_finalize = fn_finalize;
- return allocator;
-}
-
-int
-allocator_free(allocator_t* allocator_ptr)
-{
- allocator_block_t cur, next;
- allocator_node_t node;
- allocator_t allocator;
- int pos, node_size;
- fn_finalize_t fn_finalize;
- void* type;
- int rv;
-
- if(!(*allocator_ptr))
- return EINVAL;
-
-
- allocator = *allocator_ptr;
- cur = allocator->head;
-
- if(allocator->fn_finalize)
- {
- fn_finalize = allocator->fn_finalize;
- node_size = allocator->type_size + sizeof(s_allocator_node_t);
-
- while(cur)
- {
-
- /* type points to the first node */
- node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
-
- if(node->is_allocated)
- {
- type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
-
- /* apply the fn_finalize function to the first type */
-
- if((rv = (*fn_finalize)(&type)))
- return rv;
- }
-
- /*clear all the other types */
- for(pos = 1; pos < allocator->block_capacity; pos++)
- {
- node = (allocator_node_t)(((byte*)node) + node_size);
-
- if(node->is_allocated)
- {
- type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
-
- /* apply the fn_finalize function to the first type */
-
- if((rv = (*fn_finalize)(&type)))
- return rv;
- }
- }
-
- next = cur->next;
- free(cur);
- cur = next;
- }
- }
- else
- {
- while(cur)
- {
- next = cur->next;
- free(cur);
- cur = next;
- }
- }
-
- free(*allocator_ptr);
- *allocator_ptr = NULL;
-
- return 0;
-}
-
-void*
-allocator_alloc(allocator_t allocator)
-{
- allocator_node_t node;
-
- if(!allocator)
- {
- errno = EINVAL;
- return NULL;
- }
-
- /* all allocator memory is used, allocate a new block */
- if(!(allocator->free))
- if(resize(allocator))
- return NULL;
-
- node = allocator->free;
- node->is_allocated = 1;
-
- allocator->free = allocator->free->next;
- allocator->size++;
-
- return (void*)(((byte*)node) + sizeof(s_allocator_node_t));
-}
-
-int
-allocator_dealloc(allocator_t allocator, void* block)
-{
- int rv;
- allocator_node_t node;
-
- if(!allocator || !block)
- return EINVAL;
-
- if(allocator->fn_finalize)
- {
- if((rv = (*(allocator->fn_finalize))(&block)))
- return rv;
-
- memset(block, 0, allocator->type_size);
- node->is_allocated = 0;
- }
-
- /* get the node address. */
- node = (allocator_node_t)(((byte*)block) - sizeof(s_allocator_node_t));
-
- /* the node becomes the free node and the free node become the next free node.*/
- node->next = allocator->free;
- allocator->free = node;
- allocator->size--;
-
- return 0;
-}
-
-int
-allocator_get_size(allocator_t allocator)
-{
- if(!allocator)
- {
- errno = EINVAL;
- return -1;
- }
-
- return allocator->size;
-}
-
-int
-allocator_get_capacity(allocator_t allocator)
-{
- if(!allocator)
- {
- errno = EINVAL;
- return -1;
- }
-
- return allocator->capacity;
-}
-
-int
-allocator_get_type_size(allocator_t allocator)
-{
-
- if(NULL == allocator)
- {
- errno = EINVAL;
- return -1;
- }
-
- return allocator->type_size;
-}
-
-int
-allocator_is_empty(allocator_t allocator)
-{
- if(NULL == allocator)
- {
- errno = EINVAL;
- return 0;
- }
-
- return !(allocator->size);
-}
-
-
-int
-allocator_is_full(allocator_t allocator)
-{
- if(NULL == allocator)
- {
- errno = EINVAL;
- return 0;
- }
-
- return (allocator->size == allocator->capacity);
-}
-
-int
-allocator_get_block_capacity(allocator_t allocator)
-{
-
- if(!allocator)
- {
- errno = EINVAL;
- return -1;
- }
-
- return allocator->block_capacity;
-}
-
-int
-allocator_get_capacity_available(allocator_t allocator)
-{
- if(!allocator)
- {
- errno = EINVAL;
- return -1;
- }
-
- return (allocator->capacity - allocator->size);
-}
-
-int
-allocator_clear(allocator_t allocator)
-{
- allocator_block_t cur;
- allocator_node_t node;
-
- int block_capacity, node_size, type_size;
- fn_finalize_t fn_finalize;
- void* type;
- register int pos;
- int rv;
-
-
- if(!allocator)
- return EINVAL;
-
-
- if(allocator->fn_finalize)
- {
- fn_finalize = allocator->fn_finalize;
- block_capacity = allocator->block_capacity;
- type_size = allocator->type_size;
- node_size = type_size + sizeof(s_allocator_node_t);
-
- cur = allocator->head;
-
- while(cur)
- {
- /* type points to the first node */
- node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
-
- if(node->is_allocated)
- {
-
- type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
-
- /* apply the fn_finalize function to the first type */
-
- if((rv = (*fn_finalize)(&type)))
- return rv;
-
- memset(type, 0, type_size);
- node->is_allocated = 0;
- }
-
- /*clear all the other types */
- for(pos = 1; pos < block_capacity; pos++)
- {
- node = (allocator_node_t)(((byte*)node) + node_size);
-
- if(node->is_allocated)
- {
- type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
-
- /* apply the fn_finalize function to the first type */
-
- if((rv = (*fn_finalize)(&type)))
- return rv;
-
- memset(type, 0, type_size);
- node->is_allocated = 0;
- }
- }
- }
-
- cur = cur->next;
- }
-
- allocator->free = allocator->first;
- allocator->size = 0;
-
- return 0;
-}
+++ /dev/null
-
-#include <command.h>
-#include <context.h>
-#include <writer.h>
-#include <reader.h>
-#include <timer.h>
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <sys/wait.h>
-#endif
-
-#include "../include/_signal.h"
-
-
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void sig_io_handler(int status)
-{
- INFO0("*************************Got a SIGIO**************************************");
-}
-
-static void*
-command_start(void* p);
-
-command_t
-command_new(unit_t unit, context_t context, xbt_os_mutex_t mutex)
-{
- command_t command = xbt_new0(s_command_t, 1);
-
- /* get the context of the execution of the command */
- command->context = context_dup(context);
-
- /* the exit code of the command is indefinite */
- command->exit_code = INDEFINITE;
-
- /* the signal of the command is indefinite */
- command->signal = INDEFINITE_SIGNAL;
-
- command->failed = 0;
- command->interrupted = 0;
-
- /* the mutex used to safetly access to the command unit properties */
- command->mutex = mutex;
-
- if(context->output->used)
- /* instantiate the buffer filled with the content of the command stdout */
- command->output = xbt_strbuff_new();
- else
- command->output = NULL;
-
- command->pid = INDEFINITE_PID;
-
- command->stat_val = -1;
-
- /* set the unit of the command */
- command->unit = unit->root ? unit->root : unit;
-
- /* all the commands are runned in a thread */
- command->thread = NULL;
-
- command->successeded = 0;
-
- if(context->output->used)
- command->reader = reader_new(command);
- else
- command->reader = NULL;
-
- if(context->input->used)
- command->writer = writer_new(command);
- else
- command->writer = NULL;
-
- if(context->timeout != INDEFINITE)
- command->timer = timer_new(command);
- else
- command->timer = NULL;
-
- command->status = cs_initialized;
- command->reason = csr_unknown;
-
- command->stdin_fd = INDEFINITE_FD;
- command->stdout_fd = INDEFINITE_FD;
-
-
- /* register the command */
- xbt_os_mutex_acquire(mutex);
-
- vector_push_back(unit->commands, command);
-
- (command->unit->number_of_commands)++;
-
- xbt_os_mutex_release(mutex);
-
- command->fn_sig_io_handler = sig_io_handler;
-
- #ifndef WIN32
- command->killed = 0;
- #endif
-
-
-
- return command;
-}
-
-void
-command_run(command_t command)
-{
- if(!want_silent)
- INFO1("tesh %s",command->context->command_line);
-
- if(!want_just_display)
- {
- if(!interrupted)
- {
- /* start the command */
-
- if(command->context->async)
- {
- command->thread = xbt_os_thread_create("", command_start, command);
-
- if(!command->thread)
- ERROR0("xbt_os_thread_create() failed\n");
- }
- else
- command_start(command);
- }
- else
- {
- command_interrupt(command);
- }
- }
-
-}
-
-static void*
-command_start(void* p)
-{
- command_t command = (command_t)p;
- unit_t unit = command->unit;
-
- /* the command is started */
- command->status = cs_started;
-
- /* increment the number of started commands of the unit */
- xbt_os_mutex_acquire(command->mutex);
- (command->unit->number_of_started_commands)++;
- xbt_os_mutex_release(command->mutex);
-
- /* execute the command of the test */
- command_exec(command, command->context->command_line);
-
- if(cs_in_progress == command->status)
- {
- /*printf("the command %p is in progress\n",command);*/
-
- /* on attend la fin de la commande.
- * la command peut soit se terminée normalement,
- * soit se terminée à la suite d'un timeout, d'une erreur de lecture des son reader ou d'une erreur d'écriture de son writer
- * soit à la suit d'une demande d'interruption
- */
-
- command_wait(command);
-
- if(cs_failed != command->status && cs_interrupted != command->status)
- {
- /*printf("checking the command %p\n",command);*/
- command_check(command);
- }
- }
-
-
- xbt_os_mutex_acquire(command->mutex);
-
- /* if it's the last command release its unit */
- if(!unit->interrupted && unit->parsed && (unit->number_of_started_commands == (unit->number_of_failed_commands + unit->number_of_interrupted_commands + unit->number_of_successeded_commands)))
- {
- /* first release the mutex */
- unit->released = 1;
- xbt_os_mutex_release(command->mutex);
- /* the last command release the unit */
- xbt_os_sem_release(command->unit->sem);
- }
- else
- xbt_os_mutex_release(command->mutex);
-
-
- /* wait the end of the timer, the reader and the writer */
- if(command->timer && command->timer->thread)
- timer_wait(command->timer);
-
- if(command->writer && command->writer->thread)
- writer_wait(command->writer);
-
- if(command->reader && command->reader->thread)
- reader_wait(command->reader);
-
- return NULL;
-}
-
-#ifdef WIN32
-void
-command_exec(command_t command, const char* command_line)
-{
-
- STARTUPINFO si = {0}; /* contains the informations about the child process windows*/
- PROCESS_INFORMATION pi = {0}; /* contains child process informations */
- SECURITY_ATTRIBUTES sa = {0}; /* contains the security descriptor for the pipe handles */
- HANDLE child_stdin_handle[2] = {NULL}; /* child_stdin_handle[1] <-> stdout of the child process */
- HANDLE child_stdout_handle[2] = {NULL}; /* child_stdout_handle[0] <-> stdin of the child process */
- HANDLE child_stderr = NULL;
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL; /* use default security for the pipe handles */
-
- sa.bInheritHandle = TRUE; /* the pipe handles can be inherited */
-
- if(!CreatePipe(&(child_stdin_handle[0]),&(child_stdin_handle[1]),&sa,0))
- {
- ERROR1("CreatePipe1() failed (%lu)",GetLastError());
- command->failed = 1;
- command->status = cs_failed;
-
- return;
- }
-
-
- if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[1]),GetCurrentProcess(),&(child_stderr),0,TRUE,DUPLICATE_SAME_ACCESS))
- {
- ERROR1("DuplicateHandle1() failed (%lu)",GetLastError());
-
- CloseHandle(child_stdin_handle[0]);
- CloseHandle(child_stdin_handle[1]);
-
- command->failed = 1;
- command->status = cs_failed;
-
- return;
- }
-
- if(!CreatePipe(&(child_stdout_handle[0]),&(child_stdout_handle[1]),&sa,0))
- {
- ERROR1("CreatePipe2() failed (%lu)",GetLastError());
-
- CloseHandle(child_stdout_handle[0]);
- CloseHandle(child_stdout_handle[1]);
- CloseHandle(child_stdin_handle[0]);
- CloseHandle(child_stdin_handle[1]);
-
- command->failed = 1;
- command->status = cs_failed;
-
- return;
- }
-
- /* Read handle for read operations on the child std output. */
- if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[0]),GetCurrentProcess(),&(command->stdout_fd),0,FALSE, DUPLICATE_SAME_ACCESS))
- {
- CloseHandle(child_stdout_handle[0]);
- CloseHandle(child_stdout_handle[1]);
- CloseHandle(child_stdin_handle[0]);
- CloseHandle(child_stdin_handle[1]);
-
- command->failed = 1;
- command->status = cs_failed;
-
- ERROR1("DuplicateHandle2() failed (%lu)",GetLastError());
- }
-
-
- /* Write handle for write operations on the child std input. */
- if(!DuplicateHandle(GetCurrentProcess(),(child_stdout_handle[1]),GetCurrentProcess(),&(command->stdin_fd), 0,FALSE,DUPLICATE_SAME_ACCESS))
- {
- CloseHandle(child_stdout_handle[0]);
- CloseHandle(child_stdout_handle[1]);
- CloseHandle(child_stdin_handle[0]);
- CloseHandle(child_stdin_handle[1]);
-
- command->failed = 1;
- command->status = cs_failed;
-
- ERROR1("DuplicateHandle3() failed (%lu)",GetLastError());
- }
-
-
- CloseHandle(child_stdin_handle[0]);
- CloseHandle(child_stdout_handle[1]);
-
- if(command->timer)
- {
- /* launch the timer */
- timer_time(command->timer);
- }
-
- if(command->reader)
- {
- /* launch the reader */
- reader_read(command->reader);
- }
-
-
- if(command->writer)
- {
- /* launch the writer */
- writer_write(command->writer);
- }
-
- si.cb = sizeof(STARTUPINFO);
-
- si.dwFlags |= STARTF_USESTDHANDLES;
- si.hStdOutput = child_stdin_handle[1];
- si.hStdInput = child_stdout_handle[0];
- si.hStdError = child_stderr;
-
- /* launch the process */
- if(!CreateProcess(
- NULL,
- (char*)command_line,
- NULL,
- NULL,
- TRUE,
- CREATE_NO_WINDOW,
- NULL,
- NULL,
- &si,
- &pi)
- )
- {
-
- if(ERROR_FILE_NOT_FOUND == GetLastError())
- {
- exit_code = ECMDNOTFOUND;
- command_handle_failure(command,csr_command_not_found);
- }
- else
- {
- exit_code = EEXEC;
- command_handle_failure(command,csr_exec_failure);
- }
- }
- else
- {
- /* the command is running */
- command->status = cs_in_progress;
-
- /* save the pid of the command */
- command->pid = pi.hProcess;
-
- /* close non used thread handle */
- CloseHandle(pi.hThread);
-
- }
-
-
- /* close non used handles */
- CloseHandle(child_stdin_handle[1]);
- CloseHandle(child_stdout_handle[0]);
- CloseHandle(child_stderr);
-
-
-}
-#else
-void
-command_exec(command_t command, const char* command_line)
-{
- int child_stdin_fd[2] ;
- int child_stdout_fd[2];
-
- if(pipe(child_stdin_fd) || pipe(child_stdout_fd))
- {
- ERROR1("pipe() failed (%d)",errno);
- command_handle_failure(command, csr_pipe_function_failed);
-
- return;
- }
-
- command->pid= fork();
-
- if(command->pid < 0)
- {
- close(child_stdin_fd[0]);
- close(child_stdin_fd[1]);
- close(child_stdout_fd[0]);
- close(child_stdout_fd[1]);
-
- exit_code = EEXEC;
- ERROR1("fork() failed (%d)",errno);
- command_handle_failure(command,csr_exec_failure);
- }
- else
- {
- if(command->pid)
- {/* father */
-
-
- close(child_stdin_fd[0]);
- close(child_stdout_fd[1]);
-
- command->stdin_fd = child_stdin_fd[1];
-
- command->stdout_fd = child_stdout_fd[0];
-
- /* on indique que c'est le processus parent qui doit recevoir le signal */
- /*fcntl(command->stdin_fd,F_SETOWN, pid);*/
-
- if(command->reader)
- {
- /* launch the reader */
- reader_read(command->reader);
- }
-
- if(command->writer)
- {
- /* launch the writer */
- writer_write(command->writer);
- }
-
- if(command->timer)
- {
- /* launch the timer */
- timer_time(command->timer);
- }
-
- /* the command is running */
- command->status = cs_in_progress;
-
- }
- else
- {/* child */
-
-
- close(child_stdin_fd[1]);
- close(child_stdout_fd[0]);
-
- if(dup2(child_stdin_fd[0],STDIN_FILENO/*0*/) < 0)
- {
- exit_code = EEXEC;
- ERROR1("dup2() failed (%d)",errno);
- command_handle_failure(command,csr_exec_failure);
- }
-
- /*close(child_stdin_fd[0]);
- */
-
- if(dup2(child_stdout_fd[1],STDOUT_FILENO/*1*/) < 0)
- {
- exit_code = EEXEC;
- ERROR1("dup2() failed (%d)",errno);
- command_handle_failure(command,csr_exec_failure);
- }
-
- if(dup2(child_stdout_fd[1], STDERR_FILENO/*2*/) < 0)
- {
- exit_code = EEXEC;
- ERROR1("dup2() failed (%d)",errno);
- command_handle_failure(command,csr_exec_failure);
- }
-
- fcntl(command->stdin_fd, F_SETFL, fcntl(command->stdin_fd, F_GETFL) | O_NONBLOCK);
-
-
- if(command->writer)
- xbt_os_sem_release(command->writer->can_write);
-
- /*close(child_stdout_fd[1]);*/
-
- if(command->reader)
- xbt_os_sem_acquire(command->reader->started);
-
- if(command->writer)
- xbt_os_sem_acquire(command->writer->written);
-
- if(command->timer)
- xbt_os_sem_acquire(command->timer->started);
-
- if(execlp("/bin/sh", "sh", "-c", command->context->command_line, NULL) < 0)
- {
- exit_code = EEXEC;
- ERROR1("execlp() failed (%d)",errno);
- command_handle_failure(command,csr_exec_failure);
- }
- }
- }
-}
-#endif
-
-#ifdef WIN32
-void
-command_wait(command_t command)
-{
- /* wait for the command terminaison */
- DWORD rv;
-
- if(WAIT_FAILED == WaitForSingleObject(command->pid, INFINITE))
- {
- ERROR0("WaitForSingleObject() failed");
- /* TODO : see for the interruption */
- }
- else
- {
- /* don't take care of the timer or the writer or the reader failue */
- if(cs_failed != command->status && cs_interrupted != command->status)
- {
- if(!GetExitCodeProcess(command->pid,&rv))
- {
- ERROR1("GetExitCodeProcess() failed for the child %s",command->context->command_line);
- /* TODO : see for the interruption */
- }
- else
- command->stat_val = command->exit_code = rv;
- }
- }
-}
-#else
-void
-command_wait(command_t command)
-{
-
- int pid;
-
- /* let this thread wait for the child so that the main thread can detect the timeout without blocking on the wait */
-
-
- xbt_os_mutex_acquire(command->unit->mutex);
- command->unit->number_of_waiting_commands++;
- xbt_os_mutex_release(command->unit->mutex);
-
- pid = waitpid(command->pid, &(command->stat_val), 0);
-
-
- xbt_os_mutex_acquire(command->unit->mutex);
- command->unit->number_of_waiting_commands--;
- xbt_os_mutex_release(command->unit->mutex);
-
- /*printf("The %p command ended\n",command);*/
- if(pid != command->pid)
- {
- ERROR1("waitpid() failed for the child %s",command->context->command_line);
- exit_code = EWAIT;
- command_handle_failure(command, csr_wait_failure);
- }
- else
- {
- if(WIFEXITED(command->stat_val))
- command->exit_code = WEXITSTATUS(command->stat_val);
- }
-
-
-}
-#endif
-
-void
-command_check(command_t command)
-{
- int success = 1;
- cs_reason_t reason;
-
- /* we have a signal, store it */
- if(WIFSIGNALED(command->stat_val))
- {
- command->signal = strdup(signal_name(WTERMSIG(command->stat_val),command->context->signal));
- /*INFO3("the command -PID %d %s receive the signal : %s",command->pid, command->context->command_line, command->signal);*/
- }
-
- /* we have a signal and not signal is expected */
- if(WIFSIGNALED(command->stat_val) && !command->context->signal)
- {
- success = 0;
- exit_code = EUNEXPECTEDSIG;
- reason = csr_unexpected_signal_caught;
- }
-
- /* we have a signal that differ form the expected signal */
- if(success && WIFSIGNALED(command->stat_val) && command->context->signal && strcmp(signal_name(WTERMSIG(command->stat_val),command->context->signal),command->context->signal))
- {
- success = 0;
- exit_code = ESIGNOTMATCH;
- reason = csr_signals_dont_match;
- }
-
- /* we don't receipt the expected signal */
- if(success && !WIFSIGNALED(command->stat_val) && command->context->signal)
- {
- success = 0;
- exit_code = ESIGNOTRECEIPT;
- reason = csr_expected_signal_not_receipt;
- }
-
- /* if the command exit normaly and we expect a exit code : test it */
- if(success && WIFEXITED(command->stat_val) /* && INDEFINITE != command->context->exit_code*/)
- {
- /* the exit codes don't match */
- if(WEXITSTATUS(command->stat_val) != command->context->exit_code)
- {
- success = 0;
- exit_code = EEXITCODENOTMATCH;
- reason = csr_exit_codes_dont_match;
- }
- }
-
- /* if ouput handling flag is specified check the output */
- if(success && oh_check == command->context->output_handling && command->reader)
- {
- /* make sure the reader done */
- while(!command->reader->done)
- xbt_os_thread_yield();
-
- close(command->stdout_fd);
- command->stdout_fd = INDEFINITE_FD;
-
- xbt_strbuff_chomp(command->output);
- xbt_strbuff_chomp(command->context->output);
- xbt_strbuff_trim(command->output);
- xbt_strbuff_trim(command->context->output);
-
- if(command->output->used != command->context->output->used || strcmp(command->output->data, command->context->output->data))
- {
- success = 0;
- exit_code = EOUTPUTNOTMATCH;
- reason = csr_outputs_dont_match;
- }
- }
-
- if(success)
- {
- xbt_os_mutex_acquire(command->mutex);
-
- if(command->status != cs_interrupted)
- {
-
- /* signal the success of the command */
- command->status = cs_successeded;
- command->successeded = 1;
-
- /* increment the number of successeded command of the unit */
- /*xbt_os_mutex_acquire(command->mutex);*/
- (command->unit->number_of_successeded_commands)++;
- }
-
- xbt_os_mutex_release(command->mutex);
-
- }
- else
- {
- command_handle_failure(command,reason);
- }
-}
-
-#ifdef WIN32
-void
-command_kill(command_t command)
-{
- if(INDEFINITE_PID != command->pid)
- TerminateProcess(command->pid, INDEFINITE);
-}
-#else
-void
-command_kill(command_t command)
-{
- if(INDEFINITE_PID != command->pid)
- {
- /*INFO1("Kill the command - PID %d",command->pid);*/
-
- kill(command->pid,SIGTERM);
-
- if(!command->context->signal)
- command->context->signal = strdup("SIGTERM");
-
- command->exit_code = INDEFINITE;
- command->killed = 1;
-
- usleep(100);
- kill(command->pid,SIGKILL);
-
-
- }
-}
-#endif
-
-void
-command_interrupt(command_t command)
-{
- xbt_os_mutex_acquire(command->mutex);
-
- if((command->status != cs_interrupted) && (command->status != cs_failed) && (command->status != cs_successeded))
- {
- /*INFO1("Begin interrupt the command - PID %d",command->pid);*/
-
- command->status = cs_interrupted;
- command->reason = csr_interruption_request;
- command->interrupted = 1;
- xbt_os_mutex_acquire(command->unit->mutex);
- (command->unit->number_of_interrupted_commands)++;
- xbt_os_mutex_release(command->unit->mutex);
-
- if(command->pid != INDEFINITE_PID)
- command_kill(command);
-
-
- /*INFO1("End interrupt the command - PID %d",command->pid);*/
- }
-
- xbt_os_mutex_release(command->mutex);
-
-
-}
-
-void
-command_display_status(command_t command)
-{
-
- /*printf("\033[1m");*/
-
- if(cs_successeded != command->status)
- {
-
- #ifndef WIN32
- if(command->killed)
- printf(" <killed command>\n");
- #endif
-
- /* display the reason of the status of the command */
- switch(command->reason)
- {
- /* the function pipe or CreatePipe() fails */
- case csr_pipe_function_failed :
- printf(" reason : pipe() or CreatePipe() function failed (system error)\n");
- break;
-
- /* reader failure reasons*/
- case csr_read_pipe_broken :
- printf(" reason : command read pipe broken\n");
- break;
-
- case csr_read_failure :
- printf(" reason : command stdout read failed\n");
- break;
-
- /* writer failure reasons */
- case csr_write_failure :
- printf(" reason : command stdin write failed\n");
- break;
-
- case csr_write_pipe_broken :
- printf(" reason : command write pipe broken\n");
- break;
-
- /* timer reason */
- case csr_timeout :
- printf(" reason : command timeouted\n");
- break;
-
- /* command failure reason */
- case csr_command_not_found :
- printf(" reason : command not found\n");
- break;
-
- /* context failure reasons */
- case csr_exit_codes_dont_match :
- printf(" reason : exit codes don't match\n");
-
- break;
-
- case csr_outputs_dont_match :
- {
- char *diff;
- printf(" reason : ouputs don't match\n");
- diff = xbt_str_diff(command->context->output->data,command->output->data);
- printf(" output diff :\n%s\n",diff);
- free(diff);
- }
-
- break;
-
- case csr_signals_dont_match :
- printf(" reason : signals don't match\n");
- break;
-
- case csr_unexpected_signal_caught:
- printf(" reason : unexpected signal caught\n");
- break;
-
- case csr_expected_signal_not_receipt :
- printf(" reason : expected signal not receipt\n");
- break;
-
- /* system failure reasons */
- case csr_exec_failure :
- printf(" reason : can't excute the command\n");
- break;
-
- case csr_wait_failure :
- printf(" reason : wait command failure\n");
- break;
-
- /* global/local interruption */
- case csr_interruption_request :
- printf(" reason : the command receive a interruption request\n");
- break;
-
- /* unknown ? */
- case csr_unknown :
- printf(" reason : unknown \n");
- }
- }
-
- if(csr_command_not_found != command->reason && csr_exec_failure != command->reason)
- {
- if(INDEFINITE != command->exit_code)
- /* the command exit code */
- printf(" exit code : %d\n",command->exit_code);
-
- /* if an expected exit code was specified display it */
- if(INDEFINITE != command->context->exit_code)
- printf(" expected exit code : %d\n",command->context->exit_code);
- else
- printf(" no expected exit code specified\n");
-
- /* if an expected exit code was specified display it */
- if(NULL == command->context->signal)
- printf(" no expected signal specified\n");
- else
- {
- if(NULL != command->signal)
- printf(" signal : %s\n",command->signal);
-
- printf(" expected signal : %s\n",command->context->signal);
- }
-
- /* if the command has out put and the metacommand display output is specified display it */
- if(command->output && (0 != command->output->used) && (oh_display == command->context->output_handling))
- {
- xbt_dynar_t a = xbt_str_split(command->output->data, "\n");
- char *out = xbt_str_join(a,"\n||");
- xbt_dynar_free(&a);
- printf(" output :\n||%s",out);
- free(out);
- }
- }
-
- printf("\n");
-
- /*printf("\033[0m");*/
-
-
-}
-
-
-
-
-void
-command_handle_failure(command_t command, cs_reason_t reason)
-{
-
- unit_t unit = command->unit;
-
- xbt_os_mutex_acquire(command->mutex);
-
- if((command->status != cs_interrupted) && (command->status != cs_failed))
- {
- command->status = cs_failed;
- command->reason = reason;
- command->failed = 1;
-
- xbt_os_mutex_acquire(unit->mutex);
-
- /* increment the number of failed command of the unit */
- unit->number_of_failed_commands++;
-
- /* if the --ignore-failures option is not specified */
- if(!want_keep_going_unit)
- {
- if(!unit->interrupted)
- {
- /* the unit interrupted (exit for the loop) */
- unit->interrupted = 1;
-
- /* release the unit */
- xbt_os_sem_release(unit->sem);
- }
-
- /* if the --keep-going option is not specified */
- if(!want_keep_going)
- {
- if(!interrupted)
- {
- /* request an global interruption by the runner */
- interrupted = 1;
-
- /* release the runner */
- xbt_os_sem_release(units_sem);
- }
- }
- }
-
- xbt_os_mutex_release(unit->mutex);
- }
-
- xbt_os_mutex_release(command->mutex);
-}
-
-void
-command_free(command_t* command)
-{
- /* close the stdin and the stdout pipe handles */
-
- #ifdef WIN32
- if((*command)->stdin_fd != INDEFINITE_FD)
- CloseHandle((*command)->stdin_fd);
- if((*command)->stdout_fd != INDEFINITE_FD)
- CloseHandle((*command)->stdout_fd);
- #else
- if((*command)->stdin_fd != INDEFINITE_FD)
- close((*command)->stdin_fd);
-
- if((*command)->stdout_fd != INDEFINITE_FD)
- close((*command)->stdout_fd);
- #endif
-
- timer_free(&((*command)->timer));
- writer_free(&((*command)->writer));
- reader_free(&((*command)->reader));
- xbt_strbuff_free((*command)->output);
- context_free(&((*command)->context));
-
- if((*command)->signal)
- free((*command)->signal);
-
- free(*command);
- *command = NULL;
-}
-
-
-
+++ /dev/null
-#include <context.h>
-
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-#define INDEFINITE_SIGNAL NULL
-
-context_t
-context_new(void)
-{
- context_t context = xbt_new0(s_context_t, 1);
-
- context->line = NULL;
- context->command_line = NULL;
- context->exit_code = 0;
- context->timeout = INDEFINITE;
- context->input = xbt_strbuff_new();
- context->output = xbt_strbuff_new();
- context->signal = INDEFINITE_SIGNAL;
- context->output_handling = oh_check;
- context->async = 0;
-
- return context;
-}
-
-context_t
-context_dup(context_t context)
-{
-
- context_t dup = xbt_new0(s_context_t, 1);
-
- dup->line = context->line;
- dup->command_line = context->command_line;
- dup->exit_code = context->exit_code;
- dup->timeout = context->timeout;
- dup->output = NULL;
- dup->input = NULL;
- dup->signal = NULL;
-
- if(context->input->used)
- {
- dup->input = xbt_strbuff_new();
- xbt_strbuff_append(dup->input,context->input->data);
- }
-
- if(context->output->used)
- {
- dup->output = xbt_strbuff_new();
- xbt_strbuff_append(dup->output,context->output->data);
- }
-
- if(context->signal)
- dup->signal = strdup(context->signal);
-
- dup->output_handling = context->output_handling;
-
- dup->async = context->async;
-
- return dup;
-}
-
-void
-context_clear(context_t context)
-{
- context->line = NULL;
- context->command_line = NULL;
- context->exit_code = 0;
- context->timeout = INDEFINITE;
-
- if(context->input)
- xbt_strbuff_empty(context->input);
-
- if(context->output)
- xbt_strbuff_empty(context->output);
-
- if(context->signal)
- {
- free(context->signal);
- context->signal = INDEFINITE_SIGNAL;
- }
-
- context->output_handling = oh_check;
- context->async = 0;
-
-}
-
-void
-context_reset(context_t context)
-{
- context->line = NULL;
- context->command_line = NULL;
-
- if(context->input)
- xbt_strbuff_empty(context->input);
-
- if(context->output)
- xbt_strbuff_empty(context->output);
-
- if(context->signal)
- {
- free(context->signal);
- context->signal = NULL;
- }
-
- /* default expected exit code */
- context->exit_code = 0;
-
- context->output_handling = oh_check;
- context->async = 0;
-
-}
-
-void
-context_input_write(context_t context, const char* buffer)
-{
- xbt_strbuff_append(context->input, buffer);
-}
-
-void
-context_ouput_read(context_t context, const char* buffer)
-{
- xbt_strbuff_append(context->output, buffer);
-}
-
-void
-context_free(context_t* context)
-{
- if(((*context)->input))
- xbt_strbuff_free(((*context)->input));
-
- if(((*context)->output))
- xbt_strbuff_free(((*context)->output));
-
- if((*context)->signal)
- free((*context)->signal);
-
- *context = NULL;
-}
-
+++ /dev/null
-
-#include <dictionary.h>
-#include <htable.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define __DEFAULT_BLOCK_CAPACITY ((int)512)
-#define __DEFAULT_TABLE_SIZE ((int)256)
-
-static unsigned int
-hfunc(const char* key)
-{
- unsigned int hval = 5381;
- int ch;
-
- while ( (ch = *key++) )
- hval = ((hval << 5) + hval) + ch;
-
- return hval;
-}
-
-static int
-cmp_key(const char* key1, const char* key2)
-{
- return !strcmp(key1,key2);
-}
-
-
-dictionary_t
-dictionary_new(fn_finalize_t fn_finalize)
-{
- dictionary_t dictionary;
-
- if(!(dictionary = (dictionary_t)calloc(1,sizeof(s_dictionary_t))))
- return NULL;
-
- if(!(dictionary->htable = htable_new(
- __DEFAULT_BLOCK_CAPACITY,
- __DEFAULT_TABLE_SIZE,
- (fn_hfunc_t)hfunc,
- (fn_cmp_key_t)cmp_key,
- fn_finalize)))
- {
- free(dictionary);
- return NULL;
- }
-
- return dictionary;
-}
-
-int
-dictionary_set(dictionary_t dictionary,const char* key, const void* val)
-{
- if(!dictionary || !key || !val)
- return EINVAL;
-
- return htable_set(dictionary->htable,(const void*)key,val);
-}
-
-void*
-dictionary_get(dictionary_t dictionary, const char* key)
-{
-
- if(!dictionary || !key)
- {
- errno = EINVAL;
- return NULL;
- }
-
- return htable_lookup(dictionary->htable,(const void*)key);
-}
-
-
-int
-dictionary_free(dictionary_t* dictionaryptr)
-{
- int rv;
-
- if(!(*dictionaryptr))
- return EINVAL;
-
- if((rv = htable_free(&((*dictionaryptr)->htable))))
- return rv;
-
- free(*dictionaryptr);
- *dictionaryptr = NULL;
-
- return 0;
-}
-
-int
-dictionary_clear(dictionary_t dictionary)
-{
- if(!dictionary)
- return EINVAL;
-
- return htable_clear(dictionary->htable);
-}
-
-int
-dictionary_get_size(dictionary_t dictionary)
-{
- if(!dictionary)
- {
- errno = EINVAL;
- return -1;
- }
-
- return htable_get_size(dictionary->htable);
-}
-
-int
-dictionary_is_empty(dictionary_t dictionary)
-{
- if(!dictionary)
- {
- errno = EINVAL;
- return 0;
- }
-
- return htable_is_empty(dictionary->htable);
-}
-
-void*
-dictionary_remove(dictionary_t dictionary,const char* key)
-{
- if(!dictionary)
- {
- errno = EINVAL;
- return NULL;
- }
-
- return htable_remove(dictionary->htable,key);
-}
-
-
+++ /dev/null
-#include <directories.h>
-#include <directory.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-directories_t
-directories_new(void)
-{
- directories_t directories = xbt_new0(s_directories_t, 1);
-
- if(!(directories->items = vector_new(8, directory_free)))
- {
- free(directories);
- return NULL;
- }
-
- return directories;
-}
-
-int
-directories_get_size(directories_t directories)
-{
- if(!directories)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector_get_size(directories->items);
-}
-
-int
-directories_is_empty(directories_t directories)
-{
- if(!directories)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector_is_empty(directories->items);
-}
-
-int
-directories_add(directories_t directories, directory_t directory)
-{
- directory_t cur;
-
- if(!directories)
- return EINVAL;
-
- vector_rewind(directories->items);
-
- while((cur = vector_get(directories->items)))
- {
- if(!strcmp(cur->name, directory->name))
- return EEXIST;
-
- vector_move_next(directories->items);
- }
-
- return vector_push_back(directories->items, directory);
-}
-
-int
-directories_contains(directories_t directories, directory_t directory)
-{
- directory_t cur;
-
- if(!directories)
- return EINVAL;
-
- vector_rewind(directories->items);
-
- while((cur = vector_get(directories->items)))
- {
- if(!strcmp(cur->name, directory->name))
- return 1;
-
- vector_move_next(directories->items);
- }
-
- return 0;
-}
-
-int
-directories_load(directories_t directories, fstreams_t fstreams, lstrings_t suffixes)
-{
- directory_t directory;
- int rv;
-
- if(!directories || !fstreams || !suffixes)
- return EINVAL;
-
- vector_rewind(directories->items);
-
- while((directory = vector_get(directories->items)))
- {
- if((rv = directory_open(directory)))
- return rv;
-
- if((rv = directory_load(directory, fstreams, suffixes)))
- return rv;
-
- if((rv = directory_close(directory)))
- return rv;
-
- vector_move_next(directories->items);
-
-
- }
-
- return 0;
-}
-
-int
-directories_free(void** directoriesptr)
-{
- int rv;
-
- if(!(*directoriesptr))
- return EINVAL;
-
- if((rv = vector_free(&((*((directories_t*)directoriesptr))->items))))
- return rv;
-
- free(*directoriesptr);
- *directoriesptr = NULL;
-
- return 0;
-
-}
+++ /dev/null
-#include <directory.h>
-#include <fstreams.h>
-#include <fstream.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-directory_t
-directory_new(const char* name)
-{
- directory_t directory;
-
- if(!name)
- {
- errno = EINVAL;
- return NULL;
- }
-
- directory = xbt_new0(s_directory_t, 1);
-
-
- directory->name = strdup(name);
-
-
- directory->stream = NULL;
-
- return directory;
-}
-
-int
-directory_open(directory_t directory)
-{
- if(!directory || directory->stream)
- return EINVAL;
-
- if(!(directory->stream = opendir(directory->name)))
- return errno;
-
- return 0;
-}
-
-
-int
-directory_close(directory_t directory)
-{
- if(!directory)
- return EINVAL;
-
- if(!directory->stream)
- return EBADF;
-
- if(closedir(directory->stream))
- return errno;
-
- directory->stream = NULL;
- return 0;
-}
-
-int
-directory_load(directory_t directory, fstreams_t fstreams, lstrings_t suffixes)
-{
- struct dirent* entry ={0};
- s_fstream_t sfstream = {0};
- const char* suffix;
- int has_valid_suffix;
- int is_empty = 1;
- int rv;
-
- if(!directory || !fstreams)
- return EINVAL;
-
- if(!directory->stream)
- return EBADF;
-
- sfstream.directory = strdup(directory->name);
-
- while((entry = readdir(directory->stream)))
- {
- has_valid_suffix = 0;
-
- lstrings_rewind(suffixes);
-
- while((suffix = lstrings_get(suffixes)))
- {
- if(!strncmp(suffix, entry->d_name + (strlen(entry->d_name) - strlen(suffix)), strlen(suffix)))
- {
- has_valid_suffix = 1;
- break;
- }
-
- lstrings_move_next(suffixes);
- }
-
- if(!has_valid_suffix)
- continue;
-
- sfstream.name = strdup(entry->d_name);
-
- /* check first if the file stream is already in the file streams to run */
- if(fstreams_contains(fstreams, &sfstream))
- {
- WARN1("file %s already registred", entry->d_name);
- free(sfstream.name);
- continue;
- }
-
- /* add the fstream to the list of file streams to run */
- if((rv = fstreams_add(fstreams, fstream_new(directory->name, entry->d_name))))
- {
- INFO0("fstreams_add() failed");
- free(sfstream.directory);
- free(sfstream.name);
- return rv;
- }
-
- is_empty = 0;
- free(sfstream.name);
- }
-
- if(is_empty)
- WARN1("no tesh file found in the directory %s", directory->name);
-
- free(sfstream.directory);
-
-
- return 0;
-}
-
-int
-directory_free(void** directoryptr)
-{
- directory_t directory;
-
- if(!(*directoryptr))
- return EINVAL;
-
- directory = *((directory_t*)directoryptr);
-
- if(directory->stream)
- if(directory_close(directory))
- return errno;
-
- free(directory->name);
-
- free(*directoryptr);
- *directoryptr = NULL;
-
- return 0;
-}
-
-const char*
-directory_get_name(directory_t directory)
-{
- if(!directory)
- {
- errno = EINVAL;
- return NULL;
- }
-
- return (const char*)directory->name;
-}
+++ /dev/null
-#include <error.h>
-
-typedef struct s_entry
-{
- const char* name;
- int code;
- const char* string;
-}entry_t;
-
-
-static const
-entry_t err[] =
-{
- {"ENOENT", ENOENT, "No such file of directory."},
- {"ENOMEM", ENOMEM,"Insufficient memory is available."},
- {"EACCES", EACCES, "Read or search permission was denied for a component of the pathname."},
- {"ENOTDIR", ENOTDIR, "Not a directory."},
- {"EREAD", EREAD, "a read pipe operation failed"},
- {"EREADPIPE", EREADPIPE, "a pipe used to read from the stdout of a command is broken"},
- {"ETIMEOUT", ETIMEOUT, "a command is timeouted"},
- {"EWRITE", EWRITE, "a write operation failed"},
- {"EWRITEPIPE", EWRITEPIPE, "a pipe used to write to the stdin of a command is broken"},
- {"EEXEC", EEXEC, "can't execute a command"},
- {"EWAIT", EWAIT, "wait function failed"},
- {"ECMDNOTFOUND", ECMDNOTFOUND, "command is not found"},
- {"EEXITCODENOTMATCH", EEXITCODENOTMATCH, "exit codes don't match"},
- {"EOUTPUTNOTMATCH", EOUTPUTNOTMATCH, "outputs don't match"},
- {"ESIGNOTMATCH", ESIGNOTMATCH, "signals don't match"},
- {"EUNEXPECTEDSIG", EUNEXPECTEDSIG, "unexpected signal caught"},
- {"ESIGNOTRECEIPT", ESIGNOTRECEIPT, "expected signal not receipt"},
- {"EFILENOTFOUND", EFILENOTFOUND, "specified tesh file not found"},
- {"EGETCWD", EGETCWD, "system error : the getcwd() function failed"},
- {"EDIRNOTFOUND", EDIRNOTFOUND, "specified directory not found"},
- {"ECHDIR", ECHDIR, "system error : the chdir() function failed"},
- {"EPROCCMDLINE", EPROCCMDLINE, "process_command_line() failed : internal error"},
- {"ENOARG", ENOARG, "none optional argument not specified"},
- {"ENOTPOSITIVENUM", ENOTPOSITIVENUM, "argument option not strictly positive"},
- {"ESYNTAX", ESYNTAX, "syntax error"},
- {"EINVALIDTIMEOUT", EINVALIDTIMEOUT, "timeout value specified by metacommand invalid"},
- {"EINVALIDEXITCODE", EINVALIDEXITCODE, "expected exit code value specified by the metacommand invalid"},
- {"ESIGNOTSUPP", ESIGNOTSUPP, "signal specified by the metacommand not supported (Windows specific)"},
- {"ELEADTIME", ELEADTIME, "lead time"},
- {"EREADMENOTFOUND", EREADMENOTFOUND, "unable to locate the README.txt file"},
- {"EINCLUDENOTFOUND", EINCLUDENOTFOUND, "include file specified by a metacommand is not found"},
- {"ESUFFIXTOOLONG", ESUFFIXTOOLONG, "suffix is too long"},
- {"EFILENOTINSPECDIR", EFILENOTINSPECDIR,"file not found in the specified directories"},
- {"EFILENOTINCURDIR", EFILENOTINCURDIR,"file not found in the current directory"},
- {"unkwown", -1, "unknown"}
-};
-
-#include <stdio.h>
-
-const char*
-error_to_string(int errcode)
-{
- int i;
-
- for(i = 0; err[i].code != -1; i++)
- if(err[i].code == errcode)
- return err[i].string;
-
- return "unknow error";
-}
-
-const char*
-error_get_at(int pos, int* code)
-{
- if(pos < 0 || (pos > (sizeof(err)/sizeof(entry_t)) - 2))
- {
- errno = ERANGE;
- return NULL;
- }
-
- *code = err[pos].code;
- return err[pos].name;
-}
+++ /dev/null
-#include <excludes.h>
-#include <vector.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-excludes_t
-excludes_new(void)
-{
- excludes_t excludes = xbt_new0(s_excludes_t, 1);
-
- if(!(excludes->items = vector_new(8,NULL)))
- {
- free(excludes);
- return NULL;
- }
-
- return excludes;
-}
-
-int
-excludes_is_empty(excludes_t excludes)
-{
- if(!excludes)
- {
- errno = EINVAL;
- return 0;
- }
-
- return vector_is_empty(excludes->items);
-}
-
-int
-excludes_contains(excludes_t excludes, fstream_t fstream)
-{
- fstream_t cur;
-
- if(!excludes || !fstream)
- {
- errno = EINVAL;
- return 0;
- }
-
- vector_rewind(excludes->items);
-
- while((cur = vector_get(excludes->items)))
- {
- if(!strcmp(fstream->name, cur->name) && !strcmp(fstream->directory, cur->directory))
- return 1;
-
- vector_move_next(excludes->items);
- }
-
- return 0;
-}
-
-int
-excludes_add(excludes_t excludes, fstream_t fstream)
-{
- if(!excludes)
- return EINVAL;
-
- if(excludes_contains(excludes, fstream))
- return EEXIST;
-
- return vector_push_back(excludes->items, fstream);
-}
-
-int
-excludes_check(excludes_t excludes, fstreams_t fstreams)
-{
- fstream_t exclude;
- fstream_t fstream;
- int success = 1;
- int exists;
-
- if(!excludes || !fstreams)
- return EINVAL;
-
- vector_rewind(excludes->items);
-
- while((exclude = vector_get(excludes->items)))
- {
- vector_rewind(fstreams->items);
-
- while((fstream = vector_get(fstreams->items)))
- {
- exists = 0;
-
- if(!strcmp(fstream->name, exclude->name) && !strcmp(fstream->directory, exclude->directory))
- {
- exists = 1;
- break;
- }
-
- vector_move_next(fstreams->items);
- }
-
- if(!exists)
- {
- success = 0;
- WARN1("cannot exclude the file %s",exclude->name);
- }
-
- vector_move_next(excludes->items);
- }
-
- return success;
-}
-
-int
-excludes_free(void** excludesptr)
-{
- int rv;
-
- if(!(*excludesptr))
- return EINVAL;
-
- if((rv =vector_free((&(*((excludes_t*)excludesptr))->items))))
- return rv;
-
- free(*excludesptr);
- *excludesptr = NULL;
-
- return 0;
-}
+++ /dev/null
-#include <fstream.h>
-#include <errno.h>
-#include <context.h>
-#include <command.h>
-#include <unit.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-fstream_t
-fstream_new(const char* directory, const char* name)
-{
- fstream_t fstream;
-
- if(!name)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!directory && !strcmp("stdin", name))
- {
- fstream = xbt_new0(s_fstream_t, 1);
- fstream->name = strdup("stdin");
- return fstream;
- }
- else if(!directory)
- {
- errno = EINVAL;
- return NULL;
- }
-
- fstream = xbt_new0(s_fstream_t, 1);
-
- fstream->name = strdup(name);
-
- fstream->directory = strdup(directory);
- fstream->stream = NULL;
-
-
- return fstream;
-}
-
-int
-fstream_open(fstream_t fstream)
-{
- char path[MAX_PATH] = {0};
-
- if(!fstream || fstream->stream)
- return EINVAL;
-
- if(!strcmp(fstream->name, "stdin"))
- {
- fstream->stream = stdin;
- return 0;
- }
-
- sprintf(path,"%s/%s",fstream->directory, fstream->name);
-
- if(!(fstream->stream = fopen(path, "r")))
- return errno;
-
- return 0;
-}
-
-int
-fstream_close(fstream_t fstream)
-{
- if(!fstream || !strcmp(fstream->name, "stdin"))
- return EINVAL;
-
- if(!fstream->stream)
- return EBADF;
-
- fclose(fstream->stream);
- fstream->stream = NULL;
- return errno;
-}
-
-int
-fstream_free(void** fstreamptr)
-{
- if(!(*fstreamptr))
- return EINVAL;
-
- if((*((fstream_t*)fstreamptr))->stream)
- fclose((*((fstream_t*)fstreamptr))->stream);
-
- free((*((fstream_t*)fstreamptr))->name);
-
- if((*((fstream_t*)fstreamptr))->directory)
- free((*((fstream_t*)fstreamptr))->directory);
-
- free(*fstreamptr);
-
- *fstreamptr = NULL;
-
- return 0;
-
-}
-
-void
-fstream_parse(fstream_t fstream, unit_t unit, xbt_os_mutex_t mutex)
-{
- size_t len;
- char * line = NULL;
- int line_num = 0;
- char file_pos[256];
- xbt_strbuff_t buff;
- int buffbegin = 0;
- context_t context;
-
- /* Count the line length while checking wheather it's blank */
- int blankline;
- int linelen;
- /* Deal with \ at the end of the line, and call handle_line on result */
- int to_be_continued;
-
- buff=xbt_strbuff_new();
- context = context_new();
-
- while(!(unit->root->interrupted) && getline(&line, &len, fstream->stream) != -1)
- {
-
- blankline=1;
- linelen = 0;
- to_be_continued = 0;
-
- line_num++;
-
- while(line[linelen] != '\0')
- {
- if (line[linelen] != ' ' && line[linelen] != '\t' && line[linelen]!='\n' && line[linelen]!='\r')
- blankline = 0;
-
- linelen++;
- }
-
- if(blankline)
- {
- if(!context->command_line && (context->input->used || context->output->used))
- {
- ERROR1("[%d] Error: no command found in this chunk of lines.",buffbegin);
- ERROR1("Unit `%s': NOK (syntax error)", fstream->name);
-
-
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- break;
- }
- else if(unit->running_suite)
- unit->running_suite = 0;
-
-
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
-
- }
-
- context_reset(context);
- }
-
- continue;
- }
-
- if(linelen>1 && line[linelen-2]=='\\')
- {
- if(linelen>2 && line[linelen-3] == '\\')
- {
- /* Damn. Escaped \ */
- line[linelen-2] = '\n';
- line[linelen-1] = '\0';
- }
- else
- {
- to_be_continued = 1;
- line[linelen-2] = '\0';
- linelen -= 2;
-
- if (!buff->used)
- buffbegin = line_num;
- }
- }
-
- if(buff->used || to_be_continued)
- {
- xbt_strbuff_append(buff,line);
-
- if (!to_be_continued)
- {
- snprintf(file_pos,256,"%s:%d",fstream->name, buffbegin);
- unit_handle_line(unit, context, mutex, file_pos, buff->data);
- xbt_strbuff_empty(buff);
- }
- }
- else
- {
- snprintf(file_pos,256,"%s:%d",fstream->name, line_num);
- unit_handle_line(unit, context, mutex, file_pos, line);
- }
- }
-
-
-
- /* Check that last command of the file ran well */
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
- }
-
-
-
- /* Clear buffers */
- if (line)
- free(line);
-
- xbt_strbuff_free(buff);
- context_free(&context);
-}
-
-
+++ /dev/null
-#include <fstreams.h>
-#include <excludes.h>
-#include <fstream.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-fstreams_t
-fstreams_new(int capacity, fn_finalize_t fn_finalize)
-{
- fstreams_t fstreams;
-
- if(!(fstreams = (fstreams_t) calloc(1, sizeof(s_fstreams_t))))
- return NULL;
-
- if(!(fstreams->items = vector_new(capacity, fn_finalize)))
- {
- free(fstreams);
- return NULL;
- }
-
- return fstreams;
-}
-
-int
-fstreams_exclude(fstreams_t fstreams, excludes_t excludes)
-{
- vector_t to_erase;
- fstream_t fstream;
-
- if(!fstreams || !excludes)
- return EINVAL;
-
- if(excludes_is_empty(excludes))
- return 0;
-
- if(!(to_erase = vector_new(8, NULL)))
- return errno;
-
- /* collecte the file streams to exclude */
- vector_rewind(fstreams->items);
-
- while((fstream = vector_get(fstreams->items)))
- {
- if(excludes_contains(excludes, fstream))
- vector_push_back(to_erase, fstream);
-
-
- vector_move_next(fstreams->items);
- }
-
- if(!vector_is_empty(to_erase))
- {
-
- /* erase the file streams to exclude from the vector of file streams to run */
- vector_rewind(to_erase);
-
- while((fstream = vector_get(to_erase)))
- {
- vector_erase(fstreams->items, fstream);
-
- vector_move_next(to_erase);
- }
- }
-
- return vector_free(&to_erase);
-}
-
-int
-fstreams_contains(fstreams_t fstreams, fstream_t fstream)
-{
- register fstream_t cur;
-
- if(!fstreams || !fstream)
- {
- errno = EINVAL;
- return 0;
- }
-
- vector_rewind(fstreams->items);
-
- while((cur = vector_get(fstreams->items)))
- {
- if(!strcmp(cur->name, fstream->name) && !strcmp(cur->directory, fstream->directory))
- return 1;
-
- vector_move_next(fstreams->items);
- }
-
- return 0;
-}
-
-int
-fstreams_load(fstreams_t fstreams)
-{
- register fstream_t fstream;
-
- if(!fstreams )
- return EINVAL;
-
- vector_rewind(fstreams->items);
-
- while((fstream = vector_get(fstreams->items)))
- {
- fstream_open(fstream);
- vector_move_next(fstreams->items);
- }
-
-
- return 0;
-}
-
-int
-fstreams_add(fstreams_t fstreams, fstream_t fstream)
-{
- if(!fstreams)
- return EINVAL;
-
- if(vector_push_back(fstreams->items, fstream))
- return errno;
-
- return 0;
-
-}
-
-int
-fstreams_free(void** fstreamsptr)
-{
- int rv;
-
- if(!(* fstreamsptr))
- return EINVAL;
-
- if(EAGAIN != (rv = vector_free(&((*((fstreams_t*)fstreamsptr))->items))))
- return rv;
-
- free(*fstreamsptr);
-
- *fstreamsptr = NULL;
- return 0;
-}
-
-int
-fstreams_get_size(fstreams_t fstreams)
-{
- if(!fstreams)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector_get_size(fstreams->items);
-}
-
-int
-fstreams_is_empty(fstreams_t fstreams)
-{
- if(!fstreams)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector_is_empty(fstreams->items);
-}
+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <errno.h>
-#include <getpath.h>
-
-#ifndef MAX_PATH
-#define MAX_PATH 255
-#endif
-
-int
-getpath(const char* file, char** path)
-{
- char buffer1[MAX_PATH + 1] = {0};
- char buffer2[MAX_PATH + 1] = {0};
- char buffer3[MAX_PATH + 1] = {0};
- char *p1,*p2;
- size_t len = strlen(file);
- char* last_delimiter = NULL;
- struct stat buffer = {0};
-
- strncpy(buffer1, file, len);
-
- /* remove the /////// */
- while((p1 = strstr(buffer1, "//")))
- {
- if(p1[2])
- strcpy(p1, p1 + 1);
- else
- p1[1] = '\0';
- }
-
- if(*buffer1 == '~')
- {
- for(p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *p2++ = *p1++);
- *p2 = '\0';
-
- if(buffer2[0] == '\0')
- {
- char* home = getenv("HOME");
-
- if(home)
- {
- strcpy(buffer2, home);
- }
- else
- {
- struct passwd* pw = getpwuid(getuid());
-
- if(!pw)
- {
- *path = NULL;
- return -1;
- }
-
- strcpy(buffer2,pw->pw_dir);
- }
-
- strcat(buffer2, p1);
- }
-
- }
- else if (buffer1[0] != '/')
- {
-
- getcwd(buffer2, MAX_PATH + 1);
-
- if(buffer1[0] == '.' && buffer1[1] == '/')
- { /* replace */
- strcat(buffer2, &buffer1[1]);
- }
- else
- {
- strcat(buffer2, "/");
- strcat(buffer2, buffer1);
- }
- }
- else
- {
- strcpy(buffer2, buffer1); /* copy */
- }
-
- /*
- * check for /..
- */
- while((p1 = strstr( buffer2, "/.." )))
- {
- for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );
-
- if (*(p1 + 3))
- memmove(p2, p1+3, strlen(p1+3)+1);
- else
- *p2 = '\0';
- }
-
- /*
- * try to find links, and resolve them.
- */
- p1 = strtok( buffer2, "/" );
-
- *buffer3 = '\0';
-
- while(p1)
- {
- strcat( buffer3, "/" );
- strcat( buffer3, p1 );
-
- len = readlink(buffer3, buffer1, MAX_PATH);
-
- if (len != -1)
- {
- *(buffer1 + len) = '\0';
- strcpy(buffer3, buffer1 );
- }
-
- p1 = strtok( NULL, "/" );
- }
-
- if(stat(buffer3, &buffer) || !S_ISREG(buffer.st_mode))
- {
- *path = NULL;
- errno = ENOENT;
- return -1;
- }
-
- last_delimiter = strrchr(buffer3, '/');
-
- len = strlen(buffer3);
-
- if(last_delimiter)
- len -=strlen(last_delimiter);
-
- *path = (char*) calloc(len + 1, sizeof(char));
-
- if(!(*path))
- {
- *path = NULL;
- return -1;
- }
-
- strncpy(*path, buffer3, len);
-
- return len;
-}
-
-#include <stdio.h>
-
-int
-translatepath(const char* totranslate, char** translated)
-{
- char buffer1[MAX_PATH + 1] = {0};
- char buffer2[MAX_PATH + 1] = {0};
- char buffer3[MAX_PATH + 1] = {0};
- char *p1,*p2;
- size_t len;
- struct stat buffer = {0};
-
- len = strlen(totranslate);
-
- strncpy(buffer1, totranslate, len);
-
- if(!strcmp(buffer1,"."))
- {
- *translated = getcwd(NULL,0);
- return strlen(*translated);
- }
- else if(!strcmp(buffer1, "/.."))
- {
- *translated = strdup("/");
- return strlen(*translated);
- }
-
- while((p1 = strstr(buffer1, "//")))
- if(p1[2])
- strcpy(p1, p1 + 1);
- else
- p1[1] = '\0';
-
-
-
- if (buffer1[0] == '~')
- {
- for (p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *(p2++) = *(p1++));
-
- *p2 = '\0';
-
- if(buffer2[0] == '\0')
- {
- char* home = getenv("HOME");
-
- if(home)
- {
- strcpy(buffer2, home);
- }
- else
- {
- struct passwd* pw = getpwuid(getuid()); /* get entry */
-
- if(!pw)
- {
- *translated = NULL;
- return -1;
- }
-
- strcpy(buffer2,pw->pw_dir);
- }
-
- strcat(buffer2, p1);
- }
- }
- else if (*buffer1 != '/')
- {
-
- getcwd(buffer2, MAX_PATH + 1);
-
- if (*buffer1 == '.' && *(buffer1 + 1) == '/')
- {
- strcat(buffer2, buffer1+1);
- }
- else
- {
- strcat(buffer2, "/");
- strcat(buffer2, buffer1);
- }
- }
- else
- {
- strcpy(buffer2, buffer1);
- }
-
- /*
- * check for /..
- */
- while((p1 = strstr( buffer2, "/.." )))
- {
- for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );
-
- if (*(p1 + 3))
- memmove(p2, p1+3, strlen(p1+3)+1);
- else
- *p2 = '\0';
- }
-
- /*
- * try to find links.
- */
- p1 = strtok( buffer2, "/" );
-
-
- *buffer3 = '\0';
-
- while(p1)
- {
- strcat( buffer3, "/" );
- strcat( buffer3, p1 );
-
- len = readlink(buffer3, buffer1, MAX_PATH);
-
- if (len != -1)
- {
- *(buffer1 + len) = '\0';
- strcpy(buffer3, buffer1 );
- }
-
- p1 = strtok( NULL, "/" );
- }
-
- if (!(*buffer3))
- strcpy(buffer3, "/" );
-
- len = strlen(buffer3);
-
- if(stat(buffer3, &buffer) || !S_ISDIR(buffer.st_mode))
- {
- *translated = NULL;
- errno = ENOTDIR;
- return -1;
- }
-
-
- *translated = (char*) calloc(len + 1, sizeof(char));
-
- if(!(*translated))
- {
- *translated = NULL;
- return -1;
- }
-
- strncpy(*translated, buffer3, len);
-
- return len;
-}
-
-
+++ /dev/null
-
-#include <htable.h>
-
-#include <errno.h>
-#include <stdlib.h> /* calloc() free() */
-
-#define __DEFAULT_BLOCK_CAPACITY ((int)512)
-#define __DEFAULT_TABLE_SIZE ((int)256)
-
-
-static hassoc_t
-get_assoc(htable_t htable, const void* key, unsigned int* hval)
-{
- register hassoc_t hassoc;
- hassoc_t* content = htable->content;
- fn_cmp_key_t fn_cmp_key = htable->fn_cmp_key;
-
- *hval = (*(htable->fn_hfunc))(key) % htable->size;
-
- for (hassoc = content[*hval]; hassoc; hassoc = hassoc->next)
- if((*fn_cmp_key)(hassoc->key,key))
- return hassoc;
-
- return NULL;
-}
-
-
-htable_t
-htable_new(
- int block_capacity,
- int size,
- fn_hfunc_t fn_hfunc,
- fn_cmp_key_t fn_cmp_key,
- fn_finalize_t fn_finalize
-)
-{
- htable_t htable;
-
- if((block_capacity < 0) || (size < 0) ||!fn_hfunc || !fn_cmp_key)
- {
- errno = EINVAL;
- return NULL;
- }
-
-
- if(!(htable = (htable_t)calloc(1, sizeof(s_htable_t))))
- return NULL;
-
- if(!(htable->content = (hassoc_t*)calloc(size ? size : __DEFAULT_TABLE_SIZE, sizeof(hassoc_t))))
- {
- free(htable);
- return NULL;
- }
-
- if(!(htable->allocator = allocator_new(block_capacity ? block_capacity : __DEFAULT_BLOCK_CAPACITY, sizeof(s_hassoc_t),NULL)))
- {
- free(htable->content);
- free(htable);
- return NULL;
- }
-
- htable->size = size;
- htable->fn_hfunc = fn_hfunc;
- htable->fn_cmp_key = fn_cmp_key;
- htable->fn_finalize = fn_finalize;
-
- return htable;
-}
-
-int
-htable_set(htable_t htable, const void* key, const void* val)
-{
- hassoc_t hassoc;
- unsigned int hval;
-
- if(!htable || !key || !val)
- return EINVAL;
-
-
- if(!(hassoc = get_assoc(htable, key, &hval)))
- {
- if(!(hassoc = (hassoc_t)allocator_alloc(htable->allocator)))
- return errno;
-
- hassoc->key = key;
- hassoc->val = val;
-
- hassoc->next = (htable->content)[hval];
- (htable->content)[hval] = hassoc;
-
- }
- else
- hassoc->val = val;
-
- return 0;
-}
-
-void*
-htable_lookup(htable_t htable, const void* key)
-{
- hassoc_t hassoc;
- unsigned int hval;
-
- if(!htable || !key)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(hassoc = get_assoc(htable, key, &hval)))
- {
- errno = ESRCH;
- return NULL;
- }
-
- return (void*)(hassoc->val);
-
-}
-
-void*
-htable_remove(htable_t htable, const void* key)
-{
- register hassoc_t hassoc;
- hassoc_t* prev;
- fn_cmp_key_t fn_cmp_key;
- void* val;
-
- if(!htable || !key)
- {
- errno = EINVAL;
- return NULL;
- }
-
- prev = &(((htable->content)[(*(htable->fn_hfunc))(key) % htable->size]));
- fn_cmp_key =htable->fn_cmp_key;
-
- for (hassoc = *prev; hassoc; hassoc = hassoc->next)
- {
- if((*fn_cmp_key)((hassoc->key),key))
- {
- *prev = hassoc->next;
- val = (void*)hassoc->val;
-
- if(allocator_dealloc(htable->allocator,hassoc))
- return NULL;
-
- return val;
- }
-
- prev = &(hassoc->next);
- }
-
-
- errno = ESRCH;
- return NULL;
-}
-
-int
-htable_erase(htable_t htable, const void* key)
-{
- register hassoc_t hassoc;
- hassoc_t* prev;
- fn_cmp_key_t fn_cmp_key;
- void* val;
- int rv;
-
- if(!htable || !key)
- return EINVAL;
-
- prev = &(((htable->content)[(*(htable->fn_hfunc))(key) % htable->size]));
-
- fn_cmp_key =htable->fn_cmp_key;
-
- for(hassoc = *prev; hassoc; hassoc = hassoc->next)
- {
- if((*fn_cmp_key)((hassoc->key),key))
- {
- *prev = hassoc->next;
- val = (void*)hassoc->val;
-
- if((rv = allocator_dealloc(htable->allocator,hassoc)))
- return rv;
-
- if(htable->fn_finalize)
- {
- if((rv = (*(htable->fn_finalize))(&val)))
- return rv;
- }
-
- return 0;
- }
-
- prev = &(hassoc->next);
- }
-
- return ESRCH;
-}
-
-int
-htable_free(htable_t* htableptr)
-{
- htable_t htable;
- int rv;
-
- if(!(*htableptr))
- return EINVAL;
-
- htable = (htable_t)(*htableptr);
-
- if(htable->fn_finalize)
- {
- hassoc_t* content;
- register hassoc_t hassoc;
- register int pos;
- int size;
- void* val;
-
- content = htable->content;
- size = htable->size;
-
- for(pos = 0; pos < size; pos++)
- {
- for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
- {
- val = (void*)hassoc->val;
- if((rv = (*(htable->fn_finalize))(&val)))
- return rv;
- }
- }
- }
-
- free(htable->content);
-
- if((rv = allocator_free(&(htable->allocator))))
- return rv;
-
- free(*htableptr);
- *htableptr = NULL;
-
- return 0;
-}
-
-int
-htable_clear(htable_t htable)
-{
- hassoc_t* content;
- register hassoc_t hassoc;
- register int pos;
- int size;
- void* val;
- int rv;
-
- if(!htable)
- return EINVAL;
-
-
- content = htable->content;
- size = htable->size;
-
- if(htable->fn_finalize)
- {
- for(pos = 0; pos < size; pos++)
- {
- for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
- {
- val = (void*)hassoc->val;
- if((rv = (*(htable->fn_finalize))(&val)))
- return rv;
- }
-
- content[pos] = NULL;
- }
- }
- else
- {
- for(pos = 0; pos < size; pos++)
- content[pos] = NULL;
- }
-
- return allocator_clear(htable->allocator);
-}
-
-int
-htable_get_size(htable_t htable)
-{
-
- if(!htable)
- {
- errno = EINVAL;
- return -1;
- }
-
- return allocator_get_size(htable->allocator);
-}
-
-int
-htable_is_empty(htable_t htable)
-{
- if(!htable)
- {
- errno = EINVAL;
- return 0;
- }
-
- return allocator_get_size(htable->allocator);
-}
-
-int
-htable_is_autodelete(htable_t htable)
-{
-
- if(!htable)
- {
- errno = EINVAL;
- return 0;
- }
-
- return (NULL != htable->fn_finalize);
-}
-
+++ /dev/null
-
-#include <list.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#define __DEFAULT_BLOCK_CAPACITY 128
-
-static allocator_t
-allocator = NULL;
-
-static int
-ref = 0;
-
-static link_t
-link_new(void* item)
-{
- link_t link;
-
- if(!item)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(link = (link_t)allocator_alloc(allocator)))
- return NULL;
-
- link->next = link->prev = NULL;
- link->item = item;
-
- return link;
-}
-
-static int
-link_free(link_t* ref)
-{
- if(!(*ref))
- return EINVAL;
-
- allocator_dealloc(allocator, *ref);
- *ref = NULL;
-
- return 0;
-}
-
-static link_t
-search(list_t list, void* item)
-{
- register link_t cur = list->next;
-
- while(cur != ((link_t)&(list->item)))
- {
- if(cur->item == item)
- return cur;
-
- cur = cur->next;
- }
-
- errno = ESRCH;
- return NULL;
-}
-
-
-
-list_t
-list_new(fn_finalize_t fn_finalize)
-{
- list_t list = (list_t)calloc(1,sizeof(s_list_t));
-
- if(!list)
- return NULL;
-
- if(!allocator)
- {
- if(!(allocator = allocator_new(__DEFAULT_BLOCK_CAPACITY, sizeof(s_link_t), NULL)))
- {
- free(list);
- return NULL;
- }
- }
-
- list->next = list->prev = list->cur = (link_t)(&(list->item));
- list->fn_finalize = fn_finalize;
- list->pos = -1;
- list->size = 0;
-
- ref++;
-
- return list;
-}
-
-int
-list_rewind(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- list->cur = list->next;
- list->pos = 0;
-
- return 1;
-}
-
-int
-list_unwind(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- list->cur = list->prev;
- list->pos = list->size - 1;
-
- return 1;
-}
-
-int
-list_clear(list_t list)
-{
- int rv;
-
- if(!list)
- return EINVAL;
-
- if(!list->size)
- return EAGAIN;
-
- if(list->fn_finalize)
- {
- void* item;
-
- while((item = list_pop_back(list)))
- if(0 != (rv = (*(list->fn_finalize))(&item)))
- return rv;
- }
- else
- while(list_pop_back(list));
-
- return 0;
-}
-
-int
-list_free(list_t* list_ptr)
-{
- if(!(*list_ptr))
- return EINVAL;
-
- if((*list_ptr)->size)
- list_clear(*list_ptr);
-
- if(--ref)
- allocator_free(&allocator);
-
- free(*list_ptr);
- *list_ptr = NULL;
-
- return 0;
-}
-
-int
-list_push_front(list_t list, void* item)
-{
- link_t what, where, next;
-
- if(!list || !item)
- return EINVAL;
-
- if(!(what = (link_t)link_new(item)))
- return errno;
-
- where = (link_t)(&(list->item));
- next = where->next;
-
- what->prev = where;
- what->next = next;
- next->prev = what;
- where->next = what;
-
- list->size++;
-
- /* the iteration functions are now not permited */
- list->pos = -1;
- list->cur = (link_t)(&(list->item));
-
- return 0;
-}
-
-int
-list_push_back(list_t list, void* item)
-{
- link_t what, where, prev;
-
- if(!list || !item)
- return EINVAL;
-
- if(!(what = (link_t)link_new(item)))
- return errno;
-
- where = (link_t)(&(list->item));
- prev = where->prev;
- what->next = where;
- what->prev = prev;
- prev->next = what;
- where->prev = what;
-
- list->size++;
-
- /* the iteration functions are now not permited */
- list->pos = -1;
- list->cur = (link_t)(&(list->item));
-
- return 0;
-}
-
-int
-list_insert_after(list_t list, void* what, void* where)
-{
- link_t __what, __where, __next;
-
- if(!list || !what || !where)
- return EINVAL;
-
- if(!(__what = link_new(what)))
- return errno;
-
- if((__where = search(list, where)))
- return errno;
-
- __next = __where->next;
-
- __what->prev = __where;
- __what->next = __next;
- __next->prev = __what;
- __where->next = __what;
-
- list->size++;
-
- return 0;
-}
-
-int
-list_insert_before(list_t list, void* what, void* where)
-{
- link_t __what, __where, __prev;
-
- if(!list || !what || !where)
- return EINVAL;
-
- if(!(__what = link_new(what)))
- return errno;
-
- if((__where = search(list, where)))
- return errno;
-
- __prev = __where->prev;
-
- __what->next = __where;
- __what->prev = __prev;
- __prev->next = __what;
- __where->prev = __what;
-
- list->size++;
-
- return 0;
-}
-
-
-void*
-list_pop_back(list_t list)
-{
- link_t link, next, prev;
- void* item;
-
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- link = list->prev;
-
- next = link->next;
- prev = link->prev;
- prev->next = next;
- next->prev = prev;
-
- list->size--;
-
- item = link->item;
-
- link_free((link_t*)&link);
-
- /* the iteration functions are now not permited */
- list->pos = -1;
- list->cur = (link_t)(&(list->item));
-
- return item;
-}
-
-void*
-list_pop_front(list_t list)
-{
-
- link_t link, next, prev;
- void* item;
-
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- link = list->next;
-
- next = link->next;
- prev = link->prev;
- prev->next = next;
- next->prev = prev;
-
- list->size--;
-
- item = link->item;
- link_free((link_t*)&link);
-
- /* the iteration functions are now not permited */
- list->pos = -1;
- list->cur = (link_t)(&(list->item));
-
- return item;
-}
-
-int
-list_remove(list_t list, void* item)
-{
- link_t link, next, prev;
-
- if(!list || !item)
- return EINVAL;
-
- if(!list->size)
- return EAGAIN;
-
- if(!(link = search(list, item)))
- return errno;
-
- next = link->next;
- prev = link->prev;
- prev->next = next;
- next->prev = prev;
-
- list->size--;
-
- /* the iteration functions are now not permited */
- list->pos = -1;
- list->cur = (link_t)(&(list->item));
-
- return link_free((link_t*)&link);
-}
-
-int
-list_get_size(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return -1;
- }
-
- return list->size;
-}
-
-int
-list_contains(list_t list, void* item)
-{
- register link_t cur;
-
- if(!list || !item)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- cur = list->next;
-
- while(cur != ((link_t)&(list->item)))
- {
- if(cur->item == item)
- return 1;
-
- cur = cur->next;
- }
-
- return 0;
-}
-
-int
-list_is_empty(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- return !list->size;
-}
-
-int
-list_is_autodelete(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- return NULL != list->fn_finalize;
-}
-
-int
-list_move_next(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(list->cur != (link_t)(&(list->item)))
- {
- list->cur = list->cur->next;
- list->pos++;
- return 1;
- }
-
- list->pos = -1;
- errno = ERANGE;
- return 0;
-}
-
-void*
-list_get(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return list->cur->item;
-}
-
-void*
-list_set(list_t list, void* item)
-{
- void* prev_item;
-
- if(!list || !item)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
-
- prev_item = list->cur->item;
- list->cur->item = item;
-
- return prev_item;
-}
-
-void*
-list_get_at(list_t list, int pos)
-{
- register link_t cur;
-
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(pos < 0 || pos >= list->size)
- {
- errno = ERANGE;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- cur = list->next;
-
- while(pos--)
- cur = cur->next;
-
-
- return cur->item;
-}
-
-void*
-list_set_at(list_t list, int pos, void* item)
-{
- register link_t cur;
- void* prev_item;
-
- if(!list || !item)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(pos < 0 || pos >= list->size)
- {
- errno = ERANGE;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- cur = list->next;
-
- while(pos--)
- cur = cur->next;
-
- prev_item = cur->item;
- cur->item = item;
-
- return prev_item;
-
-}
-
-int
-list_move_prev(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(list->cur != (link_t)(&(list->item)))
- {
- list->cur = list->cur->prev;
- list->pos--;
- return 1;
- }
-
- list->pos = -1;
- errno = ERANGE;
- return 0;
-}
-
-static int
-seek_set(list_t list, int offset)
-{
- if(offset > list->size)
- return EINVAL;
-
- list_rewind(list);
-
- while(offset--)
- list_move_next(list);
-
- return 0;
-}
-
-static int
-seek_end(list_t list, int offset)
-{
- if(offset > list->size)
- return EINVAL;
-
- list_unwind(list);
-
- while(offset--)
- list_move_prev(list);
-
- return 0;
-}
-
-
-static int
-seek_cur(list_t list, int offset)
-{
- if(list->cur == list->next)
- {
- /* we are at the begin of the list */
- seek_set(list, offset);
- }
- else if(list->cur == list->prev)
- {
- /* we are at the end of the list */
- seek_end(list, offset);
- }
- else
- {
- if(offset > (list->size - list->pos + 1))
- return EINVAL;
-
- while(offset--)
- list_move_next(list);
-
- }
-
- return 0;
-}
-
-int
-list_seek(list_t list, int offset, int whence)
-{
- if(!list)
- return EINVAL;
-
- if(!list->size)
- return EAGAIN;
-
- switch(whence)
- {
- case SEEK_SET :
- return seek_set(list, offset);
-
- case SEEK_CUR :
- return seek_cur(list, offset);
-
- case SEEK_END :
- return seek_end(list, offset);
-
- }
-
- return EINVAL;
-}
-
-int
-list_tell(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return -1;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return -1;
- }
-
- return list->pos;
-}
-
-int
-list_getpos(list_t list, int* pos)
-{
-
- if(!list || !pos)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!list->size || (-1 == list->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- *pos = list->pos;
- return 1;
-}
-
-int
-list_setpos(list_t list, int pos)
-{
- if(!list)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(pos < 0 || pos >= list->size)
- {
- errno = ERANGE;
- return 0;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- list->cur = list->next;
- list->pos = pos;
-
- while(pos--)
- list->cur = list->cur->next;
-
- return 1;
-}
-
-
-void*
-list_get_front(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return list->next->item;
-}
-
-
-void*
-list_get_back(list_t list)
-{
- if(!list)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!list->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return list->prev->item;
-}
+++ /dev/null
-
-#include <lstrings.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <allocator.h>
-
-#define __DEFAULT_BLOCK_CAPACITY 128
-
-static allocator_t
-allocator = NULL;
-
-static int
-ref = 0;
-
-static link_t
-link_new(void* item)
-{
- link_t link;
-
- if(!item)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(link = (link_t)allocator_alloc(allocator)))
- return NULL;
-
- link->next = link->prev = NULL;
- link->item = item;
-
- return link;
-}
-
-static int
-link_free(link_t* ref)
-{
- if(!(*ref))
- return EINVAL;
-
- allocator_dealloc(allocator, *ref);
- *ref = NULL;
-
- return 0;
-}
-
-static link_t
-search(lstrings_t lstrings, const char* string)
-{
- register link_t cur = lstrings->next;
-
- while(cur != ((link_t)&(lstrings->item)))
- {
- if(!strcmp((const char*)(cur->item),string))
- return cur;
-
- cur = cur->next;
- }
-
- errno = ESRCH;
- return NULL;
-}
-
-
-
-lstrings_t
-lstrings_new(void)
-{
- lstrings_t lstrings;
-
- if(!(lstrings = (lstrings_t)calloc(1,sizeof(s_lstrings_t))))
- return NULL;
-
- if(!allocator)
- {
- if(!(allocator = allocator_new(__DEFAULT_BLOCK_CAPACITY, sizeof(s_link_t), NULL)))
- {
- free(lstrings);
- return NULL;
- }
- }
-
- lstrings->next = lstrings->prev = lstrings->cur = (link_t)(&(lstrings->item));
- lstrings->pos = -1;
- lstrings->size = 0;
-
- ref++;
- return lstrings;
-}
-
-int
-lstrings_rewind(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- lstrings->cur = lstrings->next;
- lstrings->pos = 0;
-
- return 1;
-}
-
-int
-lstrings_unwind(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- lstrings->cur = lstrings->prev;
- lstrings->pos = lstrings->size - 1;
-
- return 1;
-}
-
-int
-lstrings_clear(lstrings_t lstrings)
-{
- if(!lstrings)
- return EINVAL;
-
- if(!lstrings->size)
- return 0;
-
- while(lstrings->size)
- lstrings_pop_back(lstrings);
-
- return 0;
-}
-
-int
-lstrings_free(lstrings_t* lstrings_ptr)
-{
- if(!(*lstrings_ptr))
- return EINVAL;
-
- if((*lstrings_ptr)->size)
- lstrings_clear(*lstrings_ptr);
-
- if(--ref)
- allocator_free(&allocator);
-
- free(*lstrings_ptr);
- *lstrings_ptr = NULL;
-
- return 0;
-}
-
-int
-lstrings_push_front(lstrings_t lstrings, const char* string)
-{
- link_t what, where, next;
-
- if(!lstrings || !string)
- return EINVAL;
-
- if(!(what = (link_t)link_new((void*)string)))
- return errno;
-
- where = (link_t)(&(lstrings->item));
- next = where->next;
-
- what->prev = where;
- what->next = next;
- next->prev = what;
- where->next = what;
-
- lstrings->size++;
-
- /* the iteration functions are now not permited */
- lstrings->pos = -1;
- lstrings->cur = (link_t)(&(lstrings->item));
-
- return 0;
-}
-
-int
-lstrings_push_back(lstrings_t lstrings, const char* string)
-{
- link_t what, where, prev;
-
- if(!lstrings || !string)
- return EINVAL;
-
- if(!(what = (link_t)link_new((void*)string)))
- return errno;
-
- where = (link_t)(&(lstrings->item));
- prev = where->prev;
- what->next = where;
- what->prev = prev;
- prev->next = what;
- where->prev = what;
-
- lstrings->size++;
-
- /* the iteration functions are now not permited */
- lstrings->pos = -1;
- lstrings->cur = (link_t)(&(lstrings->item));
-
- return 0;
-}
-
-int
-lstrings_insert_after(lstrings_t lstrings, const char* what, const char* where)
-{
- link_t __what, __where, __next;
-
- if(!lstrings || !what || !where)
- return EINVAL;
-
- if(!(__what = link_new((void*)what)))
- return errno;
-
- if((__where = search(lstrings, where)))
- return errno;
-
- __next = __where->next;
-
- __what->prev = __where;
- __what->next = __next;
- __next->prev = __what;
- __where->next = __what;
-
- lstrings->size++;
-
- return 0;
-}
-
-int
-lstrings_insert_before(lstrings_t lstrings, const char* what, const char* where)
-{
- link_t __what, __where, __prev;
-
- if(!lstrings || !what || !where)
- return EINVAL;
-
- if(!(__what = link_new((void*)what)))
- return errno;
-
- if((__where = search(lstrings, where)))
- return errno;
-
- __prev = __where->prev;
-
- __what->next = __where;
- __what->prev = __prev;
- __prev->next = __what;
- __where->prev = __what;
-
- lstrings->size++;
-
- return 0;
-}
-
-const char*
-lstrings_pop_back(lstrings_t lstrings)
-{
- link_t link, next, prev;
- const char* string;
-
- if(!lstrings)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- link = lstrings->prev;
-
- next = link->next;
- prev = link->prev;
-
- prev->next = next;
- next->prev = prev;
-
- lstrings->size--;
-
- string = (const char*)link->item;
-
- link_free((link_t*)&link);
-
- /* the iteration functions are now not permited */
- lstrings->pos = -1;
- lstrings->cur = (link_t)(&(lstrings->item));
-
- return string;
-}
-
-const char*
-lstrings_pop_front(lstrings_t lstrings)
-{
-
- link_t link, next, prev;
- const char* string;
-
- if(!lstrings)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- link = lstrings->next;
-
- next = link->next;
- prev = link->prev;
- prev->next = next;
- next->prev = prev;
-
- lstrings->size--;
-
- string = (const char*)link->item;
-
- link_free((link_t*)&link);
-
- /* the iteration functions are now not permited */
- lstrings->pos = -1;
- lstrings->cur = (link_t)(&(lstrings->item));
-
- return string;
-}
-
-int
-lstrings_remove(lstrings_t lstrings, const char* string)
-{
- link_t link, next, prev;
-
- if(!lstrings || !string)
- return EINVAL;
-
- if(!lstrings->size)
- return EAGAIN;
-
- if(!(link = search(lstrings, string)))
- return errno;
-
- next = link->next;
- prev = link->prev;
- prev->next = next;
- next->prev = prev;
-
- lstrings->size--;
-
- /* the iteration functions are now not permited */
- lstrings->pos = -1;
- lstrings->cur = (link_t)(&(lstrings->item));
-
- return link_free((link_t*)&link);
-}
-
-int
-lstrings_get_size(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return -1;
- }
-
- return lstrings->size;
-}
-
-int
-lstrings_contains(lstrings_t lstrings, const char* string)
-{
- register link_t cur;
-
- if(!lstrings || !string)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- cur = lstrings->next;
-
- while(cur != ((link_t)&(lstrings->item)))
- {
- if(!strcmp((const char*)(cur->item), string))
- return 1;
-
- cur = cur->next;
- }
-
- return 0;
-}
-
-int
-lstrings_is_empty(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- return !lstrings->size;
-}
-
-int
-lstrings_move_next(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(lstrings->cur != (link_t)(&(lstrings->item)))
- {
- lstrings->cur = lstrings->cur->next;
- lstrings->pos++;
- return 1;
- }
-
- lstrings->pos = -1;
- errno = ERANGE;
- return 0;
-}
-
-const char*
-lstrings_get(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return (const char*)(lstrings->cur->item);
-}
-
-const char*
-lstrings_set(lstrings_t lstrings, const char* string)
-{
- const char* prev_string;
-
- if(!lstrings || !string)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
-
- prev_string = (const char*)(lstrings->cur->item);
- lstrings->cur->item = (void*)string;
-
- return prev_string;
-}
-
-const char*
-lstrings_get_at(lstrings_t lstrings, int pos)
-{
- register link_t cur;
-
- if(!lstrings || pos < 0 || pos >= lstrings->size)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- cur = lstrings->next;
-
- while(pos--)
- cur = cur->next;
-
-
- return (const char*)(cur->item);
-}
-
-const char*
-lstrings_set_at(lstrings_t lstrings, int pos, const char* string)
-{
- register link_t cur;
- const char* prev_string;
-
- if(!lstrings || !string)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(pos < 0 || pos >= lstrings->size)
- {
- errno = ERANGE;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- cur = lstrings->next;
-
- while(pos--)
- cur = cur->next;
-
- prev_string = (const char*)cur->item;
- cur->item = (void*)string;
-
- return prev_string;
-
-}
-
-int
-lstrings_move_prev(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(lstrings->cur != (link_t)(&(lstrings->item)))
- {
- lstrings->cur = lstrings->cur->prev;
- lstrings->pos--;
- return 1;
- }
-
- lstrings->pos = -1;
- errno = ERANGE;
- return 0;
-}
-
-static int
-seek_set(lstrings_t lstrings, int offset)
-{
- if(offset > lstrings->size)
- return EINVAL;
-
- lstrings_rewind(lstrings);
-
- while(offset--)
- lstrings_move_next(lstrings);
-
- return 0;
-}
-
-static int
-seek_end(lstrings_t lstrings, int offset)
-{
- if(offset > lstrings->size)
- return EINVAL;
-
- lstrings_unwind(lstrings);
-
- while(offset--)
- lstrings_move_prev(lstrings);
-
- return 0;
-}
-
-
-static int
-seek_cur(lstrings_t lstrings, int offset)
-{
- if(lstrings->cur == lstrings->next)
- {
- /* we are at the begin of the lstrings */
- seek_set(lstrings, offset);
- }
- else if(lstrings->cur == lstrings->prev)
- {
- /* we are at the end of the lstrings */
- seek_end(lstrings, offset);
- }
- else
- {
- if(offset > (lstrings->size - lstrings->pos + 1))
- return EINVAL;
-
- while(offset--)
- lstrings_move_next(lstrings);
-
- }
-
- return 0;
-}
-
-int
-lstrings_seek(lstrings_t lstrings, int offset, int whence)
-{
- if(!lstrings)
- return EINVAL;
-
- if(!lstrings->size)
- return EAGAIN;
-
- switch(whence)
- {
- case SEEK_SET :
- return seek_set(lstrings, offset);
-
- case SEEK_CUR :
- return seek_cur(lstrings, offset);
-
- case SEEK_END :
- return seek_end(lstrings, offset);
-
- }
-
- return EINVAL;
-}
-
-int
-lstrings_tell(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return -1;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return -1;
- }
-
- return lstrings->pos;
-}
-
-int
-lstrings_getpos(lstrings_t lstrings, int* pos)
-{
- if(!lstrings || !pos)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!lstrings->size || (-1 == lstrings->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- *pos = lstrings->pos;
- return 1;
-}
-
-int
-lstrings_setpos(lstrings_t lstrings, int pos)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(pos < 0 || pos >= lstrings->size)
- {
- errno = ERANGE;
- return 0;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- lstrings->cur = lstrings->next;
- lstrings->pos = pos;
-
- while(pos--)
- lstrings->cur = lstrings->cur->next;
-
- return 1;
-}
-
-
-const char*
-lstrings_get_front(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return (const char*)(lstrings->next->item);
-}
-
-
-const char*
-lstrings_get_back(lstrings_t lstrings)
-{
- if(!lstrings)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!lstrings->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return (const char*)(lstrings->prev->item);
-}
-
-char**
-lstrings_to_cstr(lstrings_t lstrings)
-{
- register int i;
- link_t cur;
- int size;
- char** cstr;
-
- if(!lstrings || !lstrings->size)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(cstr = (char**)calloc(lstrings->size, sizeof(char*))))
- return NULL;
-
- /* get the first link of the list */
- cur = lstrings->next;
-
- for(i = 0; i < size; i++)
- {
- if(!(cstr[i] = strdup(cur->item)))
- {
- register int j;
-
- for(j = 0; j <i; j++)
- free(cstr[j]);
-
- free(cstr);
-
- return NULL;
- }
-
- cur = cur->next;
- }
-
-
- return cstr;
-}
+++ /dev/null
-
-#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>
-
-/*
- * entry used to define the parameter of a tesh option.
- */
-typedef struct s_optentry
-{
- int c; /* the character of the option */
-
- /*
- * the type of the argument of the option
- */
- enum
- {
- flag, /* it's a flag option, by default the flag is set to zero */
- string, /* the option has strings as argument */
- number /* the option has an integral positive number as argument */
- }type;
-
- byte* value; /* the value of the option */
- byte* optional_value; /* the optional value of the option if not specified */
- const char * long_name; /* the long name of the command */
-}s_optentry_t,* optentry_t;
-
-
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(tesh,"TEst SHell utility");
-
-#ifdef WIN32
-/* Windows specific : the previous process error mode */
-static UINT
-prev_error_mode = 0;
-#endif
-
-directory_t
-root_directory = NULL;
-
-/*int
-exit_code = 0;
-*/
-
-int
-want_detail_summary = 0;
-
-/* the current version of tesh */
-static const char*
-version = "1.0";
-
-/* ------------------------------------------------------------ */
-/* options */
-/* ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------ */
-/* numbers */
-/* ------------------------------------------------------------ */
-
-
-/* --jobs is specified with arg */
-static int
-number_of_jobs = -2;
-
-/* --jobs option is not specified (use the default job count) */
-static int
-default_number_of_jobs = 1;
-
-/* --jobs is specified but has no arg (one job per unit) */
-static int
-optional_number_of_jobs = -1;
-
-/* the global timeout */
-static int
-timeout = INDEFINITE;
-
-/* ------------------------------------------------------------ */
-/* strings dlists */
-/* ------------------------------------------------------------ */
-
-/* --C change the directory before running the units */
-static directories_t
-directories = NULL;
-
-/* the include directories : see the !i metacommand */
-vector_t
-include_dirs = NULL;
-
-/* the list of tesh files to run */
-static fstreams_t
-fstreams = NULL;
-
-/* xbt logs */
-static lstrings_t
-logs = NULL;
-
-static excludes_t
-excludes = NULL;
-
-/* the ddlist of tesh file suffixes */
-static lstrings_t
-suffixes = NULL;
-
-/* ------------------------------------------------------------ */
-/* flags */
-/* ------------------------------------------------------------ */
-
-/* if 1, keep going when some commands can't be found
- * default value 0 : not keep going
- */
-int
-want_keep_going = 0;
-
-/* if 1, ignore failures from commands
- * default value : do not ignore failures
- */
-int
-want_keep_going_unit = 0;
-
-/* if 1, display tesh usage */
-static int
-want_display_usage = 0;
-
-/* if 1, display the tesh version */
-static int
-want_display_version = 0;
-
-/* if 1, the syntax of all tesh files is checked
- * before running them
- */
-static int
-want_check_syntax = 0;
-
-/* if 1, the status of all the units is display at
- * the end.
- */
-static int
-want_verbose = 0;
-
-/* if 1, the directories are displayed */
-int
-dont_want_display_directory = 0;
-
-/* if 1, just check the syntax of all the tesh files
- * do not run them.
- */
-int
-want_dry_run = 0;
-
-/* if 1, display the tesh files syntax and exit */
-static int
-want_display_semantic = 0;
-
-int
-want_silent = 0;
-
-int
-want_just_display = 0;
-
-static int
-env_overrides = 0;
-
-static int
-display_data_base = 0;
-
-static int
-question = 0;
-
-/* the semaphore used to synchronize the jobs */
-xbt_os_sem_t
-jobs_sem = NULL;
-
-/* the semaphore used by the runner to wait the end of all the units */
-xbt_os_sem_t
-units_sem = NULL;
-
-static int
-loaded = 0;
-
-int
-interrupted = 0;
-
-int
-exit_code = 0;
-
-pid_t
-pid =0;
-
-/* the table of the entries of the options */
-static const struct s_optentry opt_entries[] =
-{
- { 'C', string, (byte*)NULL, 0, "directory" },
- { 'x', string, (byte*)&suffixes, 0, "suffix" },
- { 'e', flag, (byte*)&env_overrides, 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*)&include_dirs, 0, "include-dir" },
- { 'j', number, (byte*)&number_of_jobs, (byte*) &optional_number_of_jobs, "jobs" },
- { 'k', flag, (byte*)&want_keep_going, 0, "keep-going" },
- { 'm', flag, (byte*)&want_detail_summary, 0, "detail-summary" },
- { '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"},
- { 't', number, (byte*)&timeout, 0, "timeout" },
- { 'S', flag, (byte*)&want_check_syntax, 0, "check-syntax"},
- { 'r', string, (byte*)&directories, 0, "load-directory"},
- { 'v', flag, (byte*)&want_verbose, 0, "verbose"},
- { 'F', string,(byte*)&excludes, 0, "exclude"},
- { 'l', string,(byte*)&logs,0,"log"},
- { 0, 0, 0, 0, 0}
-
-};
-
-/* the tesh usage */
-static const char* usage[] =
-{
- "Options:\n",
- " -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before running any commands.\n",
- " -e, --environment-overrides Environment variables override files.\n",
- " -f FILE, --file=FILE Read FILE as a teshfile.\n",
- " 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",
- " -i, --keep-going-unit Ignore failures from commands.\n",
- " The possible failures are :\n",
- " - the exit code differ from the expected\n",
- " - the signal throw differ from the expected\n",
- " - the output differ from the expected\n",
- " - the read pipe is broken\n",
- " - the write pipe is broken\n",
- " - the command assigned delay is outdated\n",
- " -I DIRECTORY, --include-dir=DIRECTORY Search DIRECTORY for included files.\n",
- " -j [N], --jobs[=N] Allow N commands at once; infinite commands with\n"
- " 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",
- " -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",
- " -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",
- " -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",
- " -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
-};
-
-/* the string of options of tesh */
-static char
-optstring[1 + sizeof (opt_entries) / sizeof (opt_entries[0]) * 3];
-
-/* the option table of tesh */
-static struct
-option longopts[(sizeof (opt_entries) / sizeof (s_optentry_t))];
-
-static void
-init_options(void);
-
-static int
-process_command_line(int argc, char** argv);
-
-static void
-load(void);
-
-static void
-display_usage(void);
-
-static void
-display_version(void);
-
-static void
-finalize(void);
-
-static void
-display_semantic(void);
-
-static int
-init(void);
-
-
-
-int
-main(int argc, char* argv[])
-{
- if(init() < 0)
- finalize();
-
- /* process the command line */
- 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
- */
-
- /* xbt initialization */
- if(!lstrings_is_empty(logs))
- {
- int size = lstrings_get_size(logs);
- char** cstr = lstrings_to_cstr(logs);
-
- xbt_init(&size, cstr);
-
- free(cstr);
-
- }
- else
- xbt_init(&argc, argv);
-
- /* the user wants to display the usage of tesh */
- if(want_display_usage)
- finalize();
-
- /* the user wants to display the version of tesh */
- if(want_display_version)
- {
- display_version();
- finalize();
- }
-
- /* the user wants to display the semantic of the tesh file metacommands */
- if(want_display_semantic)
- {
- display_semantic();
- finalize();
- }
-
- /* load tesh files */
- load();
-
-
- /* use by the finalize function to known if it must display the tesh usage */
- loaded = 1;
-
- if(-2 == number_of_jobs)
- {/* --jobs is not specified (use the default value) */
- number_of_jobs = default_number_of_jobs;
- }
- else if(optional_number_of_jobs == number_of_jobs)
- {/* --jobs option is specified with no args (use one job per unit) */
- number_of_jobs = fstreams_get_size(fstreams);
- }
-
- if(number_of_jobs > 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 to run");
-
- /* assume one job per file */
- number_of_jobs = fstreams_get_size(fstreams);
- }
-
- /* initialize the semaphore used to synchronize all the units */
- jobs_sem = xbt_os_sem_init(number_of_jobs);
-
- /* 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(runner_init(want_check_syntax, timeout, fstreams))
- finalize();
-
- if(want_just_display && want_silent)
- want_silent = 0;
-
- if(want_just_display && want_dry_run)
- WARN0("mismatch in the syntax : --just-check-syntax and --just-display options at same time");
-
- /* run all the units */
- runner_run();
-
-
- /* show the result of the units */
- if(want_verbose || want_dry_run)
- runner_display_status();
-
- /* all the test are runned, destroy the runner */
- runner_destroy();
-
- /* then, finalize tesh (release all the allocated memory and exits) */
- finalize();
-
- #ifndef WIN32
- return exit_code;
- #endif
-
-}
-
-/* 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;
-
-
-
- #ifdef WIN32
- /* Windows specific : don't display the general-protection-fault message box and
- * the the critical-error-handler message box (instead the system send the error
- * to the calling process : tesh)
- */
- prev_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
- #endif
-
- /* used to store the files to run */
- if(!(fstreams = fstreams_new(DEFAULT_FSTREAMS_CAPACITY, fstream_free)))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* register the current directory */
- if(!(buffer = getcwd(NULL, 0)))
- {
- exit_code = errno;
-
- if(EACCES == errno)
- ERROR0("tesh initialization failed - Insufficient permission to read the current directory");
- else
- ERROR0("Insufficient memory is available to initialize tesh : system error");
-
- return -1;
- }
-
- /* save the root directory */
- if(!(root_directory = directory_new(buffer)))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- free(buffer);
-
- /* the directories to loads */
- if(!(directories = directories_new()))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* the include directories */
- if(!(include_dirs = vector_new(DEFAULT_INCLUDE_DIRS_CAPACITY, directory_free)))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* xbt logs option */
- if(!(logs = lstrings_new()))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* the excluded files */
- if(!(excludes = excludes_new()))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* the suffixes */
- if(!(suffixes = lstrings_new()))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- /* register the default suffix ".tesh" */
- if(lstrings_push_back(suffixes,".tesh"))
- {
- ERROR0("Insufficient memory is available to initialize tesh : system error");
- return -1;
- }
-
- pid = getpid();
-
- return 0;
-}
-
-/* load -- load the tesh files to run */
-static void
-load(void)
-{
-
- /* 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);
-
- /* 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 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"));
-
- /* load the tesh files (open them) */
- fstreams_load(fstreams);
-
-}
-
-/* finalize -- cleanup all the allocated objects and display the tesh usage if needed */
-static void
-finalize(void)
-{
- /* if there is not an error and the user wants display the usage or
- * if there is an error and all the files to load are loaded, display the usage
- */
- if((!exit_code && want_display_usage) || (!exit_code && !loaded))
- display_usage();
-
- /* 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);
-
- /* delete the root directory object */
- if(root_directory)
- directory_free((void**)&root_directory);
-
- /* delete the include directories object */
- if(include_dirs)
- vector_free(&include_dirs);
-
- /* delete the list of tesh files suffixes */
- if(suffixes)
- lstrings_free(&suffixes);
-
- /* delete the xbt log options list */
- if(logs)
- lstrings_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)));
-
- /* 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')
- return;
-
- p = optstring;
-
-
- *p++ = '-';
-
- for (i = 0; opt_entries[i].c != '\0'; ++i)
- {
- /* initialize the long name of the option*/
- longopts[i].name = (opt_entries[i].long_name == 0 ? "" : opt_entries[i].long_name);
-
- /* getopt_long returns the value of val */
- longopts[i].flag = 0;
-
- /* the short option */
- longopts[i].val = opt_entries[i].c;
-
- /* add the short option in the options string */
- *p++ = opt_entries[i].c;
-
- switch (opt_entries[i].type)
- {
- /* 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;
-
- /* the option has an argument */
- case string:
- case number:
-
- *p++ = ':';
-
- if(opt_entries[i].optional_value != 0)
- {
- *p++ = ':';
-
- longopts[i].has_arg = optional_argument;
- }
- else
- longopts[i].has_arg = required_argument;
-
- break;
- }
- }
-
- *p = '\0';
- 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)
-{
- register const struct s_optentry* entry;
- register int c;
- directory_t directory;
- fstream_t fstream;
-
- /* initialize the options string of tesh */
- init_options();
-
- /* 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);
-
- if(c == EOF)
- {
- /* end of the command line or "--". */
- break;
- }
- else if (c == 1)
- {
- /* no option specified, assume it's a tesh file to run */
- char* path;
- char* delimiter;
-
- /* getpath returns -1 when the file to get the path doesn't exist */
- if(getpath(optarg, &path) < 0)
- {
- 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;
- }
-
- /* get to the last / (if any) to get the short name of the file */
- delimiter = strrchr(optarg,'/');
-
- /* create a new file stream which represents the tesh file to run */
- fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
-
- free(path);
-
- /* 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))
- {
- fstream_free((void**)&fstream);
- WARN1("File %s already specified to be run", optarg);
- }
- else
- fstreams_add(fstreams, fstream);
-
-
-
-
- }
- else if (c == '?')
- {
- /* unknown option, let getopt_long() displays the error */
- return -1;
- }
- else
- {
- for(entry = opt_entries; entry->c != '\0'; ++entry)
-
- if(c == entry->c)
- {
-
- switch (entry->type)
- {
- /* impossible */
- default:
- ERROR0("Command line processing failed : internal error");
- exit_code = EPROCCMDLINE;
- return -1;
-
-
- /* flag options */
- case flag:
- /* set the flag to one */
- *(int*) entry->value = 1;
-
- break;
-
- /* string options */
- case string:
-
- if(!optarg)
- {
- /* an option with a optional arg is specified use the entry->optional_value */
- optarg = (char*)entry->optional_value;
- }
- else if (*optarg == '\0')
- {
- /* a non optional argument is not specified */
- ERROR2("Option %c \"%s\"requires an argument",entry->c,entry->long_name);
- exit_code = ENOARG;
- return -1;
- }
-
- /* --load-directory option */
- if(!strcmp(entry->long_name,"load-directory"))
- {
- 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;
-
- }
- else
- {
- directory = directory_new(path);
- free(path);
-
- if(directories_contains(directories, directory))
- {
- directory_free((void**)&directory);
- WARN1("Directory %s already specified to be load",optarg);
- }
- else
- directories_add(directories, directory);
-
-
- }
- }
- else if(!strcmp(entry->long_name,"directory"))
- {
- 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;
- }
- else
- {
- if(!dont_want_display_directory)
- INFO1("Entering directory \"%s\"",path);
-
- chdir(path);
- free(path);
-
-
- }
- }
-
- /* --suffix option */
- else if(!strcmp(entry->long_name,"suffix"))
- {
- if(strlen(optarg) > MAX_SUFFIX)
- {
- ERROR1("Suffix %s too long",optarg);
- exit_code = ESUFFIXTOOLONG;
- return -1;
- }
-
- if(optarg[0] == '.')
- {
- char suffix[MAX_SUFFIX + 2] = {0};
- sprintf(suffix,".%s",optarg);
-
- if(lstrings_contains(suffixes, suffix))
- WARN1("Suffix %s already specified to be used", optarg);
- else
- lstrings_push_back(suffixes, suffix);
- }
- else
- {
- if(lstrings_contains(suffixes, optarg))
- WARN1("Suffix %s already specified to be used", optarg);
- else
- lstrings_push_back(suffixes, optarg);
- }
- }
- /* --file option */
- else if(!strcmp(entry->long_name,"file"))
- {
- char* path;
- char* delimiter;
-
- if(getpath(optarg, &path) < 0)
- {
- 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;
- }
-
- delimiter = strrchr(optarg,'/');
-
- fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
-
- free(path);
-
- if(fstreams_contains(fstreams, fstream))
- {
- fstream_free((void**)&fstream);
- WARN1("File %s already specified to run", optarg);
- }
- else
- fstreams_add(fstreams, fstream);
- }
- /* --include-dir option */
- else if(!strcmp(entry->long_name,"include-dir"))
- {
-
- 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;
- }
- else
- {
-
- directory = directory_new(path);
- free(path);
-
- if(vector_contains(include_dirs, directory))
- {
- directory_free((void**)&directory);
- WARN1("Include directory %s already specified to be used",optarg);
-
- }
- else
- vector_push_back(include_dirs, directory);
- }
- }
- /* --exclude option */
- else if(!strcmp(entry->long_name,"exclude"))
- {
-
- char* path;
- char* delimiter;
-
- if(getpath(optarg, &path) < 0)
- {
- 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;
- }
-
- delimiter = strrchr(optarg,'/');
-
- fstream = fstream_new(path, delimiter ? delimiter + 1 : optarg);
- free(path);
-
- if(excludes_contains(excludes, fstream))
- {
- fstream_free((void**)&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);
- }
- else
- {
- INFO1("Unexpected option %s", optarg);
- return -1;
- }
-
-
- break;
-
- /* strictly positve number options */
- case number:
-
- if ((NULL == optarg) && (argc > optind))
- {
- const char* cp;
-
- for (cp = argv[optind]; isdigit(cp[0]); ++cp)
- if(cp[0] == '\0')
- optarg = argv[optind++];
- }
-
- /* the number option is specified */
- if(NULL != optarg)
- {
- int i = atoi(optarg);
- const char *cp;
-
- for (cp = optarg; isdigit(cp[0]); ++cp);
-
- if (i < 1 || cp[0] != '\0')
- {
- 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;
- }
- /* the number option is specified but has no arg, use the optional value*/
- else
- *(int*)entry->value = *(int*) entry->optional_value;
-
- break;
-
- }
- break;
- }
- }
- }
-
- return 0;
-}
-
-static void
-display_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");
-
- for (cpp = usage; *cpp; ++cpp)
- fputs (*cpp, stream);
-
- fprintf(stream, "\nReport bugs to <martin.quinson@loria.fr | malek.cherier@loria.fr>\n");
-}
-
-static void
-display_version(void)
-{
- /* TODO : display the version of tesh */
- printf("Version :\n");
- printf(" tesh version %s : Mini shell specialized in running test units by Martin Quinson \n", version);
- printf(" and Malek Cherier\n");
- printf(" Copyright (c) 2007, 2008 Martin Quinson, Malek Cherier\n");
- printf(" All rights reserved\n");
- 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)
- printf("Report bugs to <martin.quinson@loria.fr | malek.cherier@loria.fr>");
-}
-
-static void
-display_semantic(void)
-{
- size_t len;
- char * line = NULL;
-
- FILE* stream = fopen("README.txt", "r");
-
- if(!stream)
- {
- ERROR0("Unable to locate the README.txt file");
- exit_code = EREADMENOTFOUND;
- return;
- }
-
- while(getline(&line, &len, stream) != -1)
- printf("%s",line);
-
- fclose(stream);
-}
-
-
+++ /dev/null
-#include <reader.h>
-#include <command.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void*
-reader_start_routine(void* p);
-
-reader_t
-reader_new(command_t command)
-{
- reader_t reader = xbt_new0(s_reader_t, 1);
-
- reader->thread = NULL;
- reader->command = command;
- reader->broken_pipe = 0;
- reader->failed = 0;
- reader->done = 0;
-
- reader->started = xbt_os_sem_init(0);
-
- return reader;
-}
-
-void
-reader_free(reader_t* reader)
-{
- free(*reader);
- *reader = NULL;
-}
-
-void
-reader_read(reader_t reader)
-{
- reader->thread = xbt_os_thread_create("", reader_start_routine, reader);
-}
-
-#ifdef WIN32
-static void*
-reader_start_routine(void* p)
-{
- reader_t reader = (reader_t)p;
- command_t command = reader->command;
-
- xbt_strbuff_t output = command->output;
- HANDLE stdout_fd = command->stdout_fd;
-
- DWORD number_of_bytes_to_read = 4096;
- DWORD number_of_bytes_readed;
-
- char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
-
- while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && !reader->broken_pipe)
- {
- if(!ReadFile(reader->command->stdout_fd, buffer, number_of_bytes_to_read, &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
- {
- if(GetLastError() == ERROR_BROKEN_PIPE)
- reader->broken_pipe = 1;
- else
- reader->failed = 1;
- }
- else
- {
- if(number_of_bytes_readed > 0)
- {
- buffer[number_of_bytes_readed]='\0';
- xbt_strbuff_append(output,buffer);
- }
- else
- {
- xbt_os_thread_yield();
- }
- }
- }
-
- free(buffer);
-
- if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
- {
- command_kill(command);
- exit_code = EREAD;
- command_handle_failure(command, csr_read_failure);
- }
-
- return NULL;
-}
-#else
-static void*
-reader_start_routine(void* p)
-{
- reader_t reader = (reader_t)p;
- command_t command = reader->command;
- xbt_strbuff_t output = command->output;
- int stdout_fd = command->stdout_fd;
- int number_of_bytes_readed;
- int number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;
-
- char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
- xbt_os_sem_release(reader->started);
-
- do
- {
- number_of_bytes_readed = read(stdout_fd, buffer, number_of_bytes_to_read);
-
- if(number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN)
- {
- reader->failed = 1;
- }
-
- if(number_of_bytes_readed > 0)
- {
- buffer[number_of_bytes_readed]='\0';
- xbt_strbuff_append(output,buffer);
- }
- else
- {
- usleep(100);
- }
-
- }while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && (number_of_bytes_readed != 0 /* end of file <-> normal exit */));
-
- free(buffer);
-
- if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
- {
- command_kill(command);
- exit_code = EREAD;
- command_handle_failure(command, csr_read_failure);
- }
-
- reader->done = 1;
-
- return NULL;
-}
-#endif
-
-void
-reader_wait(reader_t reader)
-{
- xbt_os_thread_join(reader->thread, NULL);
-}
+++ /dev/null
-#include <runner.h>
-#include <units.h>
-#include <unit.h>
-#include <error.h>
-#include <variable.h>
-
-#include <errno.h> /* for error code */
-#include <stdlib.h> /* for calloc() */
-#include <stdio.h>
-
-#include <sys/resource.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-extern char**
-environ;
-
-/* the unique tesh runner */
-static runner_t
-runner = NULL;
-
-/* wait for the tesh runner terminaison */
-static void
-runner_wait(void);
-
-static void*
-runner_start_routine(void* p);
-
-
-/* check the syntax of the tesh files if
- * the want_check_syntax is specified. Returns
- * 0 if the syntax is clean.
- */
-static void
-check_syntax(void);
-
-#ifdef WIN32
-
-static HANDLE
-timer_handle = NULL;
-
-static void*
-runner_start_routine(void* p)
-{
-
- LARGE_INTEGER li;
-
- li.QuadPart=- runner->timeout * 10000000; /* 10000000 = 10 000 000 * 100 nanoseconds = 1 second */
-
- /* create the waitable timer */
- timer_handle = CreateWaitableTimer(NULL, TRUE, NULL);
-
- /* set a timer to wait for timeout seconds */
- SetWaitableTimer(timer_handle, &li, 0, NULL, NULL, 0);
-
- /* wait for the timer */
- WaitForSingleObject(timer_handle, INFINITE);
-
- if(runner->waiting)
- {
- exit_code = ELEADTIME;
- runner->timeouted = 1;
- xbt_os_sem_release(units_sem);
- }
-
- return NULL;
-}
-
-#else
-static void*
-runner_start_routine(void* p)
-{
- struct timespec ts;
-
- ts.tv_sec = runner->timeout;
- ts.tv_nsec = 0L;
-
- do
- {
- nanosleep(&ts, &ts);
- }while(EINTR == errno);
-
- if(errno)
- {
- /* TODO process the error */
- }
- else
- {
- if(runner->waiting)
- {
- exit_code = ELEADTIME;
- runner->timeouted = 1;
- xbt_os_sem_release(units_sem);
- }
- }
-
- return NULL;
-}
-#endif
-
-
-int
-runner_init(int want_check_syntax, int timeout, fstreams_t fstreams)
-{
-
- int i;
- char* val;
- char buffer[MAX_PATH + 1] = {0};
- int code;
- const char* cstr;
- variable_t variable;
-
- if(!(runner = (runner_t)calloc(1, sizeof(s_runner_t))))
- return errno;
-
-
- if(!(runner->units = units_new(runner, fstreams)))
- {
- free(runner);
- runner = NULL;
- return errno;
- }
-
- runner->timeout = timeout;
- runner->timeouted = 0;
- runner->interrupted = 0;
- runner->number_of_ended_units = 0;
- runner->number_of_runned_units = 0;
- runner->waiting = 0;
-
- runner->total_of_tests = 0;
- runner->total_of_successeded_tests = 0;
- runner->total_of_failed_tests = 0;
- runner->total_of_interrupted_tests = 0;
-
- runner->total_of_units = 0;
- runner->total_of_successeded_units = 0;
- runner->total_of_failed_units = 0;
- runner->total_of_interrupted_units = 0;
-
- runner->total_of_suites = 0;
- runner->total_of_successeded_suites = 0;
- runner->total_of_failed_suites = 0;
- runner->total_of_interrupted_suites = 0;
-
- /* initialize the vector of variables */
- runner->variables = vector_new(32, (fn_finalize_t)variable_free);
-
-
- for(i = 0; environ[i] != NULL; i++)
- {
- val = strchr(environ[i], '=');
-
- if(val)
- {
- val++;
-
- if(val[0] != '\0')
- strncpy(buffer, environ[i], (val - environ[i] -1));
-
- variable = variable_new(buffer, val);
- variable->env = 1;
-
- /*printf("Add the environment variable %s %s\n", variable->name, variable->val);*/
-
- vector_push_back(runner->variables, variable);
- }
- }
-
- i = 0;
-
- while((cstr = error_get_at(i++, &code)))
- {
- sprintf(buffer,"%d",code);
- variable = variable_new(cstr, buffer);
- variable->err = 1;
- vector_push_back(runner->variables, variable);
- }
-
-
- if(want_check_syntax)
- check_syntax();
-
- return exit_code;
-
-}
-
-void
-runner_destroy(void)
-{
- units_free((void**)(&(runner->units)));
- vector_free(&runner->variables);
-
-
- #ifdef WIN32
- CloseHandle(timer_handle);
- #endif
-
- if(runner->thread)
- xbt_os_thread_join(runner->thread, NULL);
-
- free(runner);
-
- runner = NULL;
-}
-
-void
-runner_run(void)
-{
- xbt_os_mutex_t mutex;
-
- mutex = xbt_os_mutex_init();
-
- units_run_all(runner->units, mutex);
-
- if(!interrupted)
- runner_wait();
-
- /* if the runner is timeouted or receive a interruption request
- * , interrupt all the active units.
- */
- if(runner->timeouted || interrupted)
- runner_interrupt();
-
- units_join_all(runner->units);
-
- xbt_os_mutex_destroy(mutex);
-
-}
-
-static void
-runner_wait(void)
-{
- if(runner->timeout > 0)
- runner->thread = xbt_os_thread_create("", runner_start_routine, NULL);
- /* signal that the runner is waiting */
- runner->waiting = 1;
-
- /* wait for the end of all the units */
- xbt_os_sem_acquire(units_sem);
-
- runner->waiting = 0;
-}
-
-
-
-/*
- * interrupt all the active units.
- * this function is called when the lead time of the execution is reached
- * or when a failed unit requests an interruption of the execution.
- */
-void
-runner_interrupt(void)
-{
- units_interrupt_all(runner->units);
-}
-
-void
-runner_display_status(void)
-{
-
- if(!want_dry_run)
- {
- struct rusage r_usage;
-
- /*printf("\033[1m");*/
- printf("\n TEst SHell utility - mini shell specialized in running test units.\n");
- printf(" =============================================================================\n");
- /*printf("\033[0m");*/
-
- units_verbose(runner->units);
-
- /*printf("\033[1m");*/
- printf(" =====================================================================%s\n",
- runner->total_of_failed_tests ? "== FAILED": (runner->total_of_interrupted_tests || runner->total_of_interrupted_units) ? "==== INTR" : "====== OK");
-
- printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
- (runner->total_of_suites ? (1-((double)runner->total_of_failed_suites + (double)runner->total_of_interrupted_suites)/(double)runner->total_of_suites)*100.0 : 100.0),
- runner->total_of_suites, runner->total_of_successeded_suites);
-
- if(runner->total_of_failed_suites > 0)
- printf(", %d failed", runner->total_of_failed_suites);
-
- if(runner->total_of_interrupted_suites > 0)
- printf(", %d interrupted)", runner->total_of_interrupted_suites);
-
- printf(")\n");
-
- printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",
- (runner->total_of_units ? (1-((double)runner->total_of_failed_units + (double)runner->total_of_interrupted_units)/(double)runner->total_of_units)*100.0 : 100.0),
- runner->total_of_units, runner->total_of_successeded_units);
-
- if(runner->total_of_failed_units > 0)
- printf(", %d failed", runner->total_of_failed_units);
-
- if(runner->total_of_interrupted_units > 0)
- printf(", %d interrupted)", runner->total_of_interrupted_units);
-
- printf(")\n");
-
- printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
- (runner->total_of_tests ? (1-((double)runner->total_of_failed_tests + (double)runner->total_of_interrupted_tests)/(double)runner->total_of_tests)*100.0 : 100.0),
- runner->total_of_tests, runner->total_of_successeded_tests);
-
- if(runner->total_of_failed_tests > 0)
- printf(", %d failed", runner->total_of_failed_tests);
-
- if(runner->total_of_interrupted_tests > 0)
- printf(", %d interrupted)", runner->total_of_interrupted_tests);
-
- printf(")\n\n");
-
-
- if(!getrusage(RUSAGE_SELF, &r_usage))
- {
-
- printf(" Total tesh user time used: %ld second(s) %ld microsecond(s)\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);
- printf(" Total tesh system time used: %ld second(s) %ld microsecond(s)\n\n", r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
-
- if(!getrusage(RUSAGE_CHILDREN, &r_usage))
- {
- printf(" Total children user time used: %ld second(s) %ld microsecond(s)\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);
- printf(" Total children system time used: %ld second(s) %ld microsecond(s)\n\n", r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
-
- }
- }
-
- /*printf("\033[0m");*/
- }
- else
- {
- if(exit_code)
- ERROR0("Syntax error detected");
- else if(!exit_code)
- INFO0("Syntax 0K");
- }
-}
-
-static void
-check_syntax(void)
-{
- if(!want_dry_run)
- {
- want_dry_run = 1;
-
- runner_run();
-
- want_dry_run = 0;
-
- if(!exit_code)
- {
- if(!want_silent)
- INFO0("syntax checked (OK)");
-
- units_reset_all(runner->units);
-
- }
-
- }
- else
- {
- WARN0("mismatch in the syntax : --just-check-syntax and --check-syntax options at same time");
- }
-
-}
+++ /dev/null
-/* $Id: signal.c 3483 2007-05-07 11:18:56Z mquinson $ */
-
-/* signal -- what TESH needs to know about signals */
-
-/* Copyright (c) 2007 Martin Quinson. */
-/* All rights 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 <_signal.h>
-
-#ifdef WIN32
-int
-is_an_unhandled_exception(DWORD exit_code);
-
-typedef struct s_exception_entry
-{
- DWORD value;
- const char* signal;
-}s_exception_entry_t,* exception_entry_t;
-
-static const s_exception_entry_t exceptions[] =
-{
- {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV"},
- {EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "SIGSEGV"},
- {EXCEPTION_BREAKPOINT, "SIGTRAP"},
- {EXCEPTION_DATATYPE_MISALIGNMENT, "SIGBUS"},
- {EXCEPTION_FLT_DENORMAL_OPERAND, "SIGFPE"},
- {EXCEPTION_FLT_DIVIDE_BY_ZERO, "SIGFPE"},
- {EXCEPTION_FLT_INEXACT_RESULT, "SIGFPE"},
- {EXCEPTION_FLT_INVALID_OPERATION, "SIGFPE"},
- {EXCEPTION_FLT_OVERFLOW, "SIGFPE"},
- {EXCEPTION_FLT_STACK_CHECK, "SIGFPE"},
- {EXCEPTION_FLT_UNDERFLOW, "SIGFPE"},
- {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL"},
- {EXCEPTION_IN_PAGE_ERROR, "SIGSEGV"},
- {EXCEPTION_INT_DIVIDE_BY_ZERO, "SIGFPE"},
- {EXCEPTION_INT_OVERFLOW, "SIGFPE"},
- {EXCEPTION_STACK_OVERFLOW, "SIGILL"},
- {EXCEPTION_SINGLE_STEP, "SIGTRAP"},
- {EXCEPTION_NONCONTINUABLE_EXCEPTION, "SIGILL"},
- {EXCEPTION_PRIV_INSTRUCTION, "SIGILL"}
-};
-/* number of the entries in the table of exceptions */
-#define MAX_EXECPTION ((unsigned int)19)
-
-#endif
-
-typedef struct s_signal_entry {
- const char* name;
- int number;
-} s_signal_entry_t,* signal_entry_t;
-
-static const s_signal_entry_t signals[] = {
- {"SIGHUP" ,SIGHUP},
- {"SIGINT" ,SIGINT},
- {"SIGQUIT" ,SIGQUIT},
- {"SIGILL" ,SIGILL},
- {"SIGTRAP" ,SIGTRAP},
- {"SIGABRT" ,SIGABRT},
- {"SIGFPE" ,SIGFPE},
- {"SIGKILL" ,SIGKILL},
- {"SIGBUS" ,SIGBUS},
- {"SIGSEGV" ,SIGSEGV},
- {"SIGSYS" ,SIGSYS},
- {"SIGPIPE" ,SIGPIPE},
- {"SIGALRM" ,SIGALRM},
- {"SIGTERM" ,SIGTERM},
- {"SIGURG" ,SIGURG},
- {"SIGSTOP" ,SIGSTOP},
- {"SIGTSTP" ,SIGTSTP},
- {"SIGCONT" ,SIGCONT},
- {"SIGCHLD" ,SIGCHLD},
- {"SIGTTIN" ,SIGTTIN},
- {"SIGTTOU" ,SIGTTOU},
- {"SIGIO" ,SIGIO},
- {"SIGXCPU" ,SIGXCPU},
- {"SIGXFSZ" ,SIGXFSZ},
- {"SIGVTALRM",SIGVTALRM},
- {"SIGPROF" ,SIGPROF},
- {"SIGWINCH" ,SIGWINCH},
- {"SIGUSR1" ,SIGUSR1},
- {"SIGUSR2" ,SIGUSR2},
- {"SIG UNKNOWN" ,-1}
-};
-
-#ifdef WIN32
-const char* signal_name(DWORD got, char *expected)
-#else
-const char* signal_name(unsigned int got, char *expected)
-#endif
-{
- int i;
-
- #ifdef WIN32
-
- for (i=0; i < MAX_EXECPTION; i++)
- if (exceptions[i].value == got)
- return (exceptions[i].signal);
- #else
- if((got == SIGBUS) && !strcmp("SIGSEGV",expected))
- got = SIGSEGV;
-
- for (i=0; signals[i].number != -1; i++)
- if (signals[i].number == got)
- return (signals[i].name);
-
- #endif
- return bprintf("SIG UNKNOWN (%d)", got);
-}
-
-
-#ifdef WIN32
-int
-is_an_unhandled_exception(DWORD exit_code)
-{
- unsigned int i;
-
- for(i = 0; i < MAX_EXECPTION; i++)
- if(exceptions[i].value == exit_code)
- return 1;
-
- return 0;
-}
-#endif
+++ /dev/null
-#include <str_replace.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <stdio.h>
-
-int
-str_replace(char** str, const char* what, const char* with)
-{
- int pos, i;
- char* begin;
- char* buf;
-
- if(!(begin = strstr(*str, what)))
- {
- errno = ESRCH;
- return -1;
- }
-
- pos = begin - *str;
-
- i = 0;
-
- /*while(begin[i] != ' ' && begin[i] != '\n' && begin[i] != '\r' && begin[i] != '\0')
- i++;
-
- pos += i;
- */
-
- pos += strlen(what);
-
- if(begin == *str)
- {
- if(!(buf = (char*) calloc(strlen(with) + ((pos < strlen(*str)) ? strlen(*str + pos) : 0) + 1, sizeof(char))))
- return -1;
-
- strcpy(buf, with);
-
- if(pos < strlen(*str))
- strcpy(buf + strlen(with), *str + pos);
- }
- else
- {
- if(!(buf = (char*) calloc((begin - *str) + strlen(with) + ((pos < strlen(*str)) ? strlen(*str + pos) : 0) + 1, sizeof(char))))
- return -1;
-
- strncpy(buf, *str, (begin - *str));
- strcpy(buf + (begin - *str) , with);
-
-
- if(pos < strlen(*str))
- strcpy(buf + (begin - *str) + strlen(with), *str + pos);
- }
-
- free(*str);;
- *str = buf;
-
- return 0;
-
-}
-
-int
-str_replace_all(char** str, const char* what, const char* with)
-{
- int rv;
-
- while(!(rv = str_replace(str, what, with)));
-
- return (errno == ESRCH) ? 0 : -1;
-}
-
-
+++ /dev/null
-#include <suite.h>
-#include <unit.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-suite_t
-suite_new(unit_t owner, const char* description)
-{
- suite_t suite = (suite_t)malloc (sizeof (s_suite_t));
-
- suite->number = 0;
- suite->units = vector_new(DEFAULT_UNITS_CAPACITY, unit_free);
- suite->owner = owner;
- suite->description = description;
- suite->number_of_successed_units = 0;
- suite->number_of_failed_units = 0;
-
- return suite;
-}
-
-
-void
-suite_include_unit(suite_t suite, unit_t unit)
-{
- vector_push_back(suite->units, unit);
- suite->number++;
-}
-
-void
-suite_free(suite_t* suite)
-{
- if(*suite)
- {
- vector_free(&((*suite)->units));
- free(*suite);
- *suite = NULL;
- }
-}
-
+++ /dev/null
-#include <timer.h>
-#include <command.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void*
-timer_start_routine(void* p);
-
-ttimer_t
-timer_new(command_t command)
-{
- ttimer_t timer = xbt_new0(s_timer_t, 1);
-
- timer->command = command;
- timer->thread = NULL;
- timer->timeouted = 0;
- timer->started = xbt_os_sem_init(0);
-
- return timer;
-}
-
-void
-timer_free(ttimer_t* timer)
-{
- free(*timer);
- *timer = NULL;
-}
-
-void
-timer_time(ttimer_t timer)
-{
- timer->thread = xbt_os_thread_create("", timer_start_routine, timer);
-}
-
-static void*
-timer_start_routine(void* p)
-{
- ttimer_t timer = (ttimer_t)p;
- command_t command = timer->command;
-
- int now = (int)time(NULL);
- int lead_time = now + command->context->timeout;
-
- xbt_os_sem_release(timer->started);
-
- while(!command->failed && !command->interrupted && !command->successeded && !timer->timeouted)
- {
- if(lead_time >= now)
- {
- xbt_os_thread_yield();
- /*usleep(100);*/
- now = (int)time(NULL);
- }
- else
- {
- /*printf("the timer is timeouted\n");*/
- timer->timeouted = 1;
- }
- }
-
- if(timer->timeouted && !command->failed && !command->successeded && !command->interrupted)
- {
- command_handle_failure(command, csr_timeout);
- command_kill(command);
- exit_code = ETIMEOUT;
-
- }
-
- return NULL;
-}
-
-void
-timer_wait(ttimer_t timer)
-{
- xbt_os_thread_join(timer->thread, NULL);
-}
+++ /dev/null
-#include <unit.h>
-#include <suite.h>
-#include <command.h>
-#include <context.h>
-#include <fstream.h>
-#include <variable.h>
-#include <str_replace.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void
-replace_variables(unit_t unit, char** line)
-{
- variable_t variable;
- char name[MAX_PATH + 1] = {0};
-
- /* check if some commands have setted some environment variables */
- /* TODO */
-
- /*printf("repalce all the variables of the line %s\n", *line);*/
-
-
- xbt_os_mutex_acquire(unit->mutex);
-
- vector_rewind(unit->runner->variables);
-
- while((variable = vector_get(unit->runner->variables)))
- {
- sprintf(name, "$%s", variable->name);
- /*printf("try to replace all the variable %s\n",name);*/
- str_replace_all(line, name, variable->val);
-
- vector_move_next(unit->runner->variables);
- memset(name, 0, MAX_PATH + 1);
- }
-
- xbt_os_mutex_release(unit->mutex);
-
- /*printf("line after the variables replacement %s\n",*line);*/
-
-}
-
-/* the unit thread start routine */
-static void*
-unit_start(void* p);
-
-unit_t
-unit_new(runner_t runner, unit_t root, unit_t owner, fstream_t fstream)
-{
- unit_t unit = xbt_new0(s_unit_t, 1);
-
- /* set the owner of the unit */
- unit->runner = runner;
-
- unit->fstream = fstream;
-
- unit->sem = NULL;
-
- unit->commands = vector_new(DEFAULT_COMMANDS_CAPACITY, (fn_finalize_t)command_free);
- unit->includes = vector_new(DEFAULT_INCLUDES, (fn_finalize_t)unit_free);
-
- unit->thread = NULL;
-
- unit->number_of_started_commands = 0;
- unit->number_of_interrupted_commands = 0;
- unit->number_of_failed_commands = 0;
- unit->number_of_successeded_commands = 0;
- unit->number_of_terminated_commands = 0;
- unit->number_of_waiting_commands = 0;
- unit->interrupted = 0;
- unit->failed = 0;
- unit->successeded = 0;
- unit->parsed = 0;
- unit->released = 0;
- unit->parsing_include_file = 0;
-
-
- unit->owner = owner;
-
- unit->root = root ? root : unit;
-
-
- unit->number = 0;
- unit->suites = vector_new(DEFAULT_SUITES_CAPACITY, (fn_finalize_t)unit_free);
- unit->owner = owner;
-
- unit->running_suite = 0;
- unit->is_suite = 0;
- unit->description = NULL;
-
- return unit;
-
-}
-
-/*void
-unit_add_suite(unit_t unit, suite_t suite)
-{
- vector_push_back(unit->suites, suite);
-}*/
-
-int
-unit_free(void** unitptr)
-{
- unit_t* __unitptr = (unit_t*)unitptr;
-
- vector_free(&((*__unitptr)->commands));
-
- vector_free(&((*__unitptr)->includes));
-
- vector_free(&((*__unitptr)->suites));
-
- /* if the unit is interrupted during its run, the semaphore is NULL */
- if((*__unitptr)->sem)
- xbt_os_sem_destroy((*__unitptr)->sem);
-
- if((*__unitptr)->description)
- free((*__unitptr)->description);
-
- free((*__unitptr)->suites);
-
- free(*__unitptr);
-
- *__unitptr = NULL;
-
- return 0;
-}
-
-static void*
-unit_start(void* p)
-{
-
- xbt_os_thread_t thread;
- xbt_os_mutex_t mutex;
- /*context_t context;*/
- int i, j;
-
- unit_t unit = (unit_t)p;
- unit_t include;
-
- xbt_os_mutex_acquire(unit->mutex);
- unit->runner->number_of_runned_units++;
- xbt_os_mutex_release(unit->mutex);
-
- /* try to acquire the jobs semaphore to start */
- xbt_os_sem_acquire(jobs_sem);
-
- mutex = xbt_os_mutex_init();
- /*context = context_new();*/
-
- if(want_dry_run)
- INFO1("checking unit %s...",unit->fstream->name);
-
- /* parse the file */
- /*unit_parse(unit, context, mutex, unit->fstream->name, unit->fstream->stream);*/
-
- fstream_parse(unit->fstream, unit, mutex);
-
-
- /* if the unit is not interrupted and not failed the unit, all the file is parsed
- * so all the command are launched
- */
-
-
- if(!unit->interrupted)
- {
- unit->parsed = 1;
-
- /* all the commands have terminate before the end of the parsing of the tesh file
- * so the unit release the semaphore itself
- */
- if(!unit->released && (unit->number_of_started_commands == (unit->number_of_failed_commands + unit->number_of_interrupted_commands + unit->number_of_successeded_commands)))
- {
- /*INFO1("the unit %s is released", unit->fstream->name);*/
- xbt_os_sem_release(unit->sem);
- }
- else
- {
-
- INFO1("the unit %s is not released", unit->fstream->name);
- INFO1("number of started commands %d", unit->number_of_started_commands);
- INFO1("number of failed commands %d", unit->number_of_failed_commands);
- INFO1("number of interrupted commands %d", unit->number_of_interrupted_commands);
- INFO1("number of successeded commands %d", unit->number_of_successeded_commands);
- INFO1("number of waiting commands %d", unit->number_of_waiting_commands);
-
-
- if(unit->number_of_waiting_commands)
- {
- command_t command;
- int i, j;
-
- for(i = 0; i < vector_get_size(unit->includes) ; i++)
- {
- include = vector_get_at(unit->includes, i);
-
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command = vector_get_at(include->commands, j);
-
- if(command->status == cs_in_progress)
- {
- INFO2("the command %s PID %d is in process", command->context->command_line, command->pid);
-
- if(command->writer->done)
- INFO2("the writer of the command %s PID %d done", command->context->command_line, command->pid);
- else
- INFO2("the writer of the command %s PID %d doesn't done", command->context->command_line, command->pid);
- }
- }
-
- }
- }
- }
-
- }
-
- /* wait the end of all the commands or a command failure or an interruption */
- xbt_os_sem_acquire(unit->sem);
-
-
- if(unit->interrupted)
- {
- command_t command;
-
- /* interrupt all the running commands of the unit */
- for(i = 0; i < vector_get_size(unit->commands); i++)
- {
- command = vector_get_at(unit->commands, i);
-
- if(command->status == cs_in_progress)
- command_interrupt(command);
- }
-
- for(i = 0; i < vector_get_size(unit->includes); i++)
- {
- include = vector_get_at(unit->includes, i);
-
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command = vector_get_at(include->commands, j);
-
- if(command->status == cs_in_progress)
- command_interrupt(command);
- }
- }
-
- }
-
- /* wait the end of the threads */
- for(i = 0; i < vector_get_size(unit->commands); i++)
- {
- command_t command = vector_get_at(unit->commands, i);
- thread = command->thread;
-
- if(thread)
- xbt_os_thread_join(thread,NULL);
- }
-
- for(i = 0; i < vector_get_size(unit->includes); i++)
- {
- include = vector_get_at(unit->includes, i);
-
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command_t command = vector_get_at(include->commands, j);
- thread = command->thread;
-
- if(thread)
- xbt_os_thread_join(thread,NULL);
- }
- }
-
- /*context_free(&context);*/
-
- xbt_os_mutex_destroy(mutex);
-
-
- xbt_os_mutex_acquire(unit->mutex);
-
- /* increment the number of ended units */
- unit->runner->number_of_ended_units++;
-
- /* it's the last unit, release the runner */
- if(/*!unit->interrupted &&*/ (unit->runner->number_of_runned_units == unit->runner->number_of_ended_units))
- {
- if(unit->number_of_successeded_commands == unit->number_of_commands)
- unit->successeded = 1;
-
- /* first release the mutex */
- xbt_os_mutex_release(unit->mutex);
-
- xbt_os_sem_release(units_sem);
- }
- else
- xbt_os_mutex_release(unit->mutex);
-
- /* release the jobs semaphore, then the next unit can start */
- xbt_os_sem_release(jobs_sem);
-
- return NULL;
-
-}
-
-void
-unit_parse(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, FILE* stream)
-{
- size_t len;
- char * line = NULL;
- int line_num=0;
- char file_pos[256];
- xbt_strbuff_t buff;
- int buffbegin = 0;
-
- /* Count the line length while checking wheather it's blank */
- int blankline;
- int linelen;
- /* Deal with \ at the end of the line, and call handle_line on result */
- int to_be_continued;
-
- buff=xbt_strbuff_new();
-
- while(!unit->interrupted && getline(&line, &len, stream) != -1)
- {
- blankline=1;
- linelen = 0;
- to_be_continued = 0;
-
- line_num++;
-
- while(line[linelen] != '\0')
- {
- if (line[linelen] != ' ' && line[linelen] != '\t' && line[linelen]!='\n' && line[linelen]!='\r')
- blankline = 0;
-
- linelen++;
- }
-
- if(blankline)
- {
- if(!context->command_line && (context->input->used || context->output->used))
- {
- ERROR1("[%d] Error: no command found in this chunk of lines.",buffbegin);
-
- if(unit->parsing_include_file)
- ERROR1("Unit `%s': NOK (syntax error)", unit->fstream->name);
- else
- ERROR2("Unit `%s' inclued in `%s' : NOK (syntax error)", file_name, unit->fstream->name);
-
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- break;
- }
- else if(unit->running_suite)
- {
- /* TODO */
- }
-
-
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
- }
-
-
- continue;
-
- }
-
- if(linelen>1 && line[linelen-2]=='\\')
- {
- if (linelen>2 && line[linelen-3] == '\\')
- {
- /* Damn. Escaped \ */
- line[linelen-2] = '\n';
- line[linelen-1] = '\0';
- }
- else
- {
- to_be_continued = 1;
- line[linelen-2] = '\0';
- linelen -= 2;
-
- if (!buff->used)
- buffbegin = line_num;
- }
- }
-
- if(buff->used || to_be_continued)
- {
- xbt_strbuff_append(buff,line);
-
- if (!to_be_continued)
- {
- snprintf(file_pos,256,"%s:%d",file_name,buffbegin);
- unit_handle_line(unit, context, mutex, file_pos, buff->data);
- xbt_strbuff_empty(buff);
- }
- }
- else
- {
- snprintf(file_pos,256,"%s:%d",file_name,line_num);
- unit_handle_line(unit, context, mutex, file_pos, line);
- }
- }
-
- /* Check that last command of the file ran well */
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
- }
-
- /* Clear buffers */
- if (line)
- free(line);
-
- xbt_strbuff_free(buff);
-}
-
-
-
-void
-unit_handle_line(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char * filepos, char *line)
-{
- char* line2;
- /* Search end */
- xbt_str_rtrim(line+2,"\n");
-
- line2 = strdup(line);
-
- replace_variables(unit, &line2);
-
- switch (line2[0])
- {
- case '#':
- break;
-
- case '$':
- case '&':
-
- context->async = (line2[0] == '&');
-
- /* further trim useless chars which are significant for in/output */
- xbt_str_rtrim(line2+2," \t");
-
- /* Deal with CD commands here, not in rctx */
- if(!strncmp("cd ",line2 + 2, 3))
- {
- /*char *dir=line2+4; */
- char* dir = strdup(line2 + 4);
-
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
- }
-
- /* search begining */
- while (*(dir++) == ' ');
-
- dir--;
-
- VERB1("Saw cd '%s'",dir);
-
-
- if(!want_dry_run)
- {
-
- if(chdir(dir))
- {
- ERROR2("Chdir to %s failed: %s",dir,strerror(errno));
- ERROR1("Test suite `%s': NOK (system error)", unit->fstream->name);
- exit_code = ECHDIR;
- unit_handle_failure(unit);
- }
-
-
- }
-
- break;
- } /* else, pushline */
- else
- {
- unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
- break;
- }
-
- case '<':
- case '>':
- case '!':
- unit_pushline(unit, context, mutex, filepos, line2[0], line2+2 /* pass '$ ' stuff*/);
- break;
-
- case 'p':
- if(!want_dry_run)
- INFO2("[%s] %s",filepos,line2+2);
- break;
-
- case 'P':
- if(!want_dry_run)
- CRITICAL2("[%s] %s",filepos,line2+2);
- break;
-
- case 'D':
- if(unit->description)
- WARN2("description already specified %s %s", filepos, line2);
- else
- unit->description = strdup(line2 + 2);
- break;
-
- default:
- ERROR2("[%s] Syntax error: %s",filepos, line2);
- ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- break;
- }
-
- free(line2);
-}
-
-void
-unit_pushline(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* filepos, char kind, char *line)
-{
- switch (kind)
- {
- case '$':
- case '&':
-
- if(context->command_line)
- {
- command_t command;
-
- if(context->output->used || context->input->used)
- {
- ERROR2("[%s] More than one command in this chunk of lines (previous: %s).\nDunno which input/output belongs to which command.",filepos,context->command_line);
- ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- return;
- }
-
- if(!want_dry_run)
- {
- command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
-
- VERB1("[%s] More than one command in this chunk of lines",filepos);
- }
-
- context->command_line = strdup(line);
-
-
- context->line = strdup(filepos);
- /*INFO2("[%s] %s",filepos,context->command_line);*/
-
- break;
-
- case '<':
- xbt_strbuff_append(context->input,line);
- xbt_strbuff_append(context->input,"\n");
- break;
-
- case '>':
- xbt_strbuff_append(context->output,line);
- xbt_strbuff_append(context->output,"\n");
- break;
-
- case '!':
-
- if(context->command_line)
- {
- if(!want_dry_run)
- {
- command_t command = command_new(unit, context, mutex);
- command_run(command);
- }
-
- context_reset(context);
- }
-
- if(!strncmp(line,"timeout no",strlen("timeout no")))
- {
- VERB1("[%s] (disable timeout)", filepos);
- context->timeout = INDEFINITE;
- }
- else if(!strncmp(line,"timeout ",strlen("timeout ")))
- {
- int i = 0;
- char* p = line + strlen("timeout ");
-
- while(p[i] != '\0')
- {
- if(!isdigit(p[i]))
- {
- exit_code = ESYNTAX;
- ERROR2("Invalid timeout value `%s' at %s ", line + strlen("timeout "), filepos);
- unit_handle_failure(unit);
- }
-
- i++;
- }
-
- context->timeout = atoi(line + strlen("timeout"));
- VERB2("[%s] (new timeout value: %d)",filepos,context->timeout);
-
- }
- else if (!strncmp(line,"expect signal ",strlen("expect signal ")))
- {
- context->signal = strdup(line + strlen("expect signal "));
-
- #ifdef WIN32
- if(!strstr(context->signal,"SIGSEGVSIGTRAPSIGBUSSIGFPESIGILL"))
- {
- exit_code = ESYNTAX;
- /*ERROR2("Signal `%s' not supported at %s", line + strlen("expect signal "), filepos);*/
- unit_handle_failure(unit);
- }
- #endif
-
- xbt_str_trim(context->signal," \n");
- VERB2("[%s] (next command must raise signal %s)", filepos, context->signal);
-
- }
- else if (!strncmp(line,"expect return ",strlen("expect return ")))
- {
-
- int i = 0;
- char* p = line + strlen("expect return ");
-
-
- while(p[i] != '\0')
- {
- if(!isdigit(p[i]))
- {
- exit_code = ESYNTAX;
- ERROR2("Invalid exit code value `%s' at %s ", line + strlen("expect return "), filepos);
- unit_handle_failure(unit);
- }
-
- i++;
- }
-
- context->exit_code = atoi(line+strlen("expect return "));
- VERB2("[%s] (next command must return code %d)",filepos, context->exit_code);
-
- }
- else if (!strncmp(line,"output ignore",strlen("output ignore")))
- {
- context->output_handling = oh_ignore;
- VERB1("[%s] (ignore output of next command)", filepos);
-
- }
- else if (!strncmp(line,"output display",strlen("output display")))
- {
- context->output_handling = oh_display;
- VERB1("[%s] (ignore output of next command)", filepos);
-
- }
- else if(!strncmp(line,"include ", strlen("include ")))
- {
- char* p1;
- char* p2;
-
- p1 = line + strlen("include");
-
- while(*p1 == ' ' || *p1 == '\t')
- p1++;
-
-
- if(p1[0] == '\0')
- {
-
- exit_code = ESYNTAX;
- ERROR1("include file not specified %s ", filepos);
- unit_handle_failure(unit);
- }
- else
- {
- char file_name[MAX_PATH + 1] = {0};
-
- /*INFO1("p1 is %s",p1);*/
-
- p2 = p1;
-
- while(*p2 != '\0' && *p2 != ' ' && *p2 != '\t')
- {
- /*INFO1("p2 is %s",p2);*/
- p2++;
-
- }
- /*INFO1("p2 is %s",p2);*/
-
- strncpy(file_name, p1, p2 - p1);
-
- /*INFO1("filename is %s", file_name);*/
-
- if(p2[0] != '\0')
- while(*p2 == ' ' || *p2 == '\t')
- p2++;
-
- unit_handle_include(unit, context, mutex, file_name, p2[0] != '\0' ? p2 : NULL);
-
- }
- }
- else if(!strncmp(line,"suite ", strlen("suite ")))
- {
- unit_handle_suite(unit, context, mutex, line + strlen("suite "));
- }
- else if(!strncmp(line,"unsetenv ", strlen("unsetenv ")))
- {
- int i;
- int number_of_variables;
- int exists = 0;
- int env;
- variable_t variable;
- char* name = line + strlen("unsetenv ");
-
- xbt_os_mutex_acquire(unit->mutex);
-
- number_of_variables = vector_get_size(unit->runner->variables);
-
- for(i = 0; i < number_of_variables; i++)
- {
- variable = vector_get_at(unit->runner->variables, i);
-
- if(!strcmp(variable->name, name))
- {
- env = variable->env;
- exists = 1;
- break;
- }
- }
-
- if(env)
- {
- if(exists)
- vector_erase_at(unit->runner->variables, i);
- else
- WARN3("environment variable %s not found %s %s", name, line, filepos);
- }
- else
- {
- if(exists)
- WARN3("%s is an not environment variable use unset metacommand to delete it %s %s", name, line, filepos);
- else
- WARN3("%s environment variable not found %s %s", name, line, filepos);
- }
-
- xbt_os_mutex_release(unit->mutex);
-
-
- }
- else if(!strncmp(line,"setenv ", strlen("setenv ")))
- {
- char* val;
- char name[MAX_PATH + 1] = {0};
- char* p;
-
- p = line + strlen("setenv ");
-
- val = strchr(p, '=');
-
- if(val)
- {
- variable_t variable;
- int exists = 0;
- int env = 0;
- val++;
-
- /* syntax error */
- if(val[0] == '\0')
- {
-
- exit_code = ESYNTAX;
- ERROR2("indefinite variable value %s %s", line, filepos);
- unit_handle_failure(unit);
- }
-
-
-
- strncpy(name, p, (val - p -1));
-
- /* test if the variable is already registred */
-
- xbt_os_mutex_acquire(unit->mutex);
-
- vector_rewind(unit->runner->variables);
-
- while((variable = vector_get(unit->runner->variables)))
- {
-
- if(!strcmp(variable->name, name))
- {
- variable->env = 1;
- exists = 1;
- break;
- }
-
- vector_move_next(unit->runner->variables);
- }
-
- /* if the variable is already registred, update its value;
- * otherwise register it.
- */
- if(exists)
- {
- if(env)
- {
- free(variable->val);
- variable->val = strdup(val);
- setenv(variable->name, variable->val, 1);
- }
- else
- WARN3("%s variable already exists %s %s", name, line, filepos);
- }
- else
- {
- variable = variable_new(name, val);
- variable->env = 1;
-
- vector_push_back(unit->runner->variables, variable);
-
- setenv(variable->name, variable->val, 0);
- }
-
- xbt_os_mutex_release(unit->mutex);
-
- }
- }
- else if(!strncmp(line,"unset ", strlen("unset ")))
- {
- int i;
- int number_of_variables;
- int exists = 0;
- int env;
- int err;
- variable_t variable;
- char* name = line + strlen("unset ");
-
- xbt_os_mutex_acquire(unit->mutex);
-
- number_of_variables = vector_get_size(unit->runner->variables);
-
- for(i = 0; i < number_of_variables; i++)
- {
- variable = vector_get_at(unit->runner->variables, i);
-
- if(!strcmp(variable->name, name))
- {
- env = variable->env;
- err = variable->err;
- exists = 1;
- break;
- }
- }
-
- if(!env)
- {
- if(exists)
- vector_erase_at(unit->runner->variables, i);
- else
- WARN3("variable %s not found %s %s", name, line, filepos);
- }
- else if(env)
- {
- WARN3("%s is an environment variable use unsetenv metacommand to delete it %s %s", name, line, filepos);
- }
- else
- {
- WARN3("%s is an error variable : you are not allowed to delete it %s %s", name, line, filepos);
- }
- xbt_os_mutex_release(unit->mutex);
-
- }
- else
- {
- /* may be a variable */
- char* val;
- char name[MAX_PATH + 1] = {0};
-
- val = strchr(line, '=');
-
- if(val)
- {
- variable_t variable;
- int exists = 0;
- val++;
-
- /* syntax error */
- if(val[0] == '\0')
- {
-
- exit_code = ESYNTAX;
- ERROR2("indefinite variable value %s %s", line, filepos);
- unit_handle_failure(unit);
- }
-
-
- /* assume it's a varibale */
- strncpy(name, line, (val - line -1));
-
- xbt_os_mutex_acquire(unit->mutex);
-
- /* test if the variable is already registred */
-
- vector_rewind(unit->runner->variables);
-
- while((variable = vector_get(unit->runner->variables)))
- {
-
- if(!strcmp(variable->name, name))
- {
- exists = 1;
- break;
- }
-
- vector_move_next(unit->runner->variables);
- }
-
- /* if the variable is already registred, update its value;
- * otherwise register it.
- */
- if(exists)
- {
- free(variable->val);
- variable->val = strdup(val);
- }
- else
- vector_push_back(unit->runner->variables,variable_new(name, val));
-
- xbt_os_mutex_release(unit->mutex);
-
- }
- else
- {
- ERROR2("%s: Malformed metacommand: %s",filepos,line);
- ERROR1("Test suite `%s': NOK (syntax error)",unit->fstream->name);
-
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- return;
- }
- }
-
-
- break;
- }
-}
-
-
-void
-unit_handle_failure(unit_t unit)
-{
-
- if(!want_keep_going_unit)
- {
- unit_t root = unit->root ? unit->root : unit;
-
- if(!root->interrupted)
- {
- /* the unit interrupted (exit for the loop) */
- root->interrupted = 1;
-
- /* release the unit */
- xbt_os_sem_release(root->sem);
- }
-
- /* if the --keep-going option is not specified */
- if(!want_keep_going)
- {
- if(!interrupted)
- {
- /* request an global interruption by the runner */
- interrupted = 1;
-
- /* release the runner */
- xbt_os_sem_release(units_sem);
- }
- }
- }
-}
-
-void
-unit_run(unit_t unit, xbt_os_mutex_t mutex)
-{
- if(!interrupted)
- {
- unit->mutex = mutex;
-
- unit->sem = xbt_os_sem_init(0);
-
- /* start the unit */
- unit->thread = xbt_os_thread_create("", unit_start, unit);
- }
- else
- /* the unit is interrupted by the runner before its starting
- * in this case the unit semaphore is NULL take care of that
- * in the function unit_free()
- */
- unit->interrupted = 1;
-
-
-}
-
-void
-unit_interrupt(unit_t unit)
-{
- /* interrupt the loop */
- unit->interrupted = 1;
- xbt_os_sem_release(unit->sem);
-}
-
-void
-display_title(const char* description)
-{
- int i;
- char title[80];
- int len = strlen(description);
-
- title[0]=' ';
-
- for (i = 1; i < 79; i++)
- title[i]='=';
-
- title[i++]='\n';
- title[79]='\0';
-
- sprintf(title + 40 - (len + 4)/2, "[ %s ]",description);
- title[40 + (len + 5 ) / 2] = '=';
-
- printf("\n%s\n",title);
-}
-
-void
-unit_verbose(unit_t unit)
-{
- int i, j, k;
- command_t command;
- unit_t include;
- unit_t suite;
- char* p;
- char title[MAX_PATH + 1] = {0};
-
- int number_of_tests = 0; /* number of tests of a unit contained by this unit */
- int number_of_failed_tests = 0; /* number of failed test of a unit contained by this unit */
- int number_of_successeded_tests = 0; /* number of successeded tests of a unit contained by this unit */
- int number_of_interrupted_tests = 0; /* number of interrupted tests of a unit contained by this unit */
-
- int number_of_tests_of_suite = 0; /* number of tests of a suite contained by this unit */
- int number_of_interrupted_tests_of_suite = 0; /* number of interrupted tests of a suite contained by this unit */
- int number_of_failed_tests_of_suite = 0; /* number of failed tests of a suite contained by this unit */
- int number_of_successeded_tests_of_suite = 0; /* number of successeded tests of a suite contained by this */
-
- int number_of_units = 0; /* number of units contained by a suite */
- int number_of_failed_units = 0; /* number of failed units contained by a suite */
- int number_of_successeded_units = 0; /* number of successeded units contained by a suite */
- int number_of_interrupted_units = 0; /* number of interrupted units contained by a suite */
-
- int total_of_tests = 0; /* total of the tests contained by this unit */
- int total_of_failed_tests = 0; /* total of failed tests contained by this unit */
- int total_of_successeded_tests = 0; /* total of successeded tests contained by this unit */
- int total_of_interrupted_tests = 0; /* total of interrupted tests contained by this unit */
-
- int total_of_units = 0; /* total of units contained by this unit */
- int total_of_failed_units = 0; /* total of failed units contained by this unit */
- int total_of_successeded_units = 0; /* total of successeded units contained by this unit */
- int total_of_interrupted_units = 0; /* total of interrutped units contained by this unit */
-
- int total_of_suites = 0; /* total of suites contained by this unit */
- int total_of_failed_suites = 0; /* total of failed suites contained by this unit */
- int total_of_successeded_suites = 0; /* total of successeded suites contained by this unit */
- int total_of_interrupted_suites = 0; /* total of interrupted suites contained by this unit */
-
-
- if(unit->description)
- strcpy(title, unit->description);
- else
- sprintf(title, "file : %s",unit->fstream->name);
-
- if(unit->interrupted)
- strcat(title, " (interrupted)");
-
- display_title(title);
-
- number_of_tests = vector_get_size(unit->commands);
-
-
- /* tests */
- for(i = 0; i < number_of_tests; i++)
- {
- command = vector_get_at(unit->commands, i);
-
- if(command->status == cs_interrupted)
- number_of_interrupted_tests++;
- else if(command->status == cs_failed)
- number_of_failed_tests++;
- else if(command->status == cs_successeded)
- number_of_successeded_tests++;
-
- }
-
- if(number_of_tests)
- {
- asprintf(&p," Test(s): .........................................................................");
-
- p[70] = '\0';
- printf("%s", p);
- free(p);
-
- if(number_of_failed_tests > 0)
- printf(".. failed\n");
- else if(number_of_interrupted_tests > 0)
- printf("interrupt\n");
- else
- printf(".... ..ok\n");
-
-
- for(i = 0; i < number_of_tests; i++)
- {
- command = vector_get_at(unit->commands, i);
-
- printf(" %s: %s [%s]\n",
- command->status == cs_interrupted ? "INTR "
- : command->status == cs_failed ? "FAILED"
- : command->status == cs_successeded ? "PASS "
- : "UNKNWN",
- command->context->command_line,
- command->context->line);
-
- if(want_detail_summary)
- command_display_status(command);
-
- }
-
- printf(" =====================================================================%s\n",
- number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
-
- printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
- ((1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0),
- number_of_tests, number_of_successeded_tests);
-
- if(number_of_failed_tests > 0)
- printf(", %d failed", number_of_failed_tests);
-
- if(number_of_interrupted_tests > 0)
- printf(", %d interrupted)", number_of_interrupted_tests);
-
- printf(")\n\n");
-
- total_of_tests = number_of_tests;
- total_of_failed_tests = number_of_failed_tests;
- total_of_interrupted_tests = number_of_interrupted_tests;
- total_of_successeded_tests = number_of_successeded_tests;
- }
-
-
-
- /* includes */
-
- total_of_failed_units = total_of_interrupted_units = total_of_successeded_units = 0;
-
- number_of_failed_units = number_of_successeded_units = number_of_interrupted_units = 0;
-
- number_of_units = vector_get_size(unit->includes);
-
- for(i = 0; i < number_of_units ; i++)
- {
- include = vector_get_at(unit->includes, i);
-
- number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
-
- number_of_tests = vector_get_size(include->commands);
-
- for(j = 0; j < number_of_tests; j++)
- {
- command = vector_get_at(include->commands, j);
-
- if(command->status == cs_interrupted)
- number_of_interrupted_tests++;
- else if(command->status == cs_failed)
- number_of_failed_tests++;
- else if(command->status == cs_successeded)
- number_of_successeded_tests++;
- }
-
- asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
-
- p[70] = '\0';
- printf("%s", p);
- free(p);
-
-
- if(number_of_failed_tests > 0)
- {
- total_of_failed_units++;
- printf(".. failed\n");
- }
- else if(number_of_interrupted_tests > 0)
- {
- total_of_interrupted_units++;
- printf("interrupt\n");
- }
- else
- {
- total_of_successeded_units++;
- printf(".... ..ok\n");
- }
-
- if(want_detail_summary)
- {
-
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command = vector_get_at(include->commands, j);
-
- printf(" %s: %s [%s]\n",
- command->status == cs_interrupted ? "INTR "
- : command->status == cs_failed ? "FAILED"
- : command->status == cs_successeded ? "PASS "
- : "UNKNWN",
- command->context->command_line,
- command->context->line);
-
- command_display_status(command);
- }
-
-
- }
-
- printf(" =====================================================================%s\n",
- number_of_failed_tests ? "== FAILED": number_of_interrupted_tests ? "==== INTR" : "====== OK");
-
-
- printf(" Summary: Test(s): %.0f%% ok (%d test(s): %d ok",
- (number_of_tests ? (1-((double)number_of_failed_tests + (double)number_of_interrupted_tests)/(double)number_of_tests)*100.0 : 100.0),
- number_of_tests, number_of_successeded_tests);
-
- if(number_of_failed_tests > 0)
- printf(", %d failed", number_of_failed_tests);
-
- if(number_of_interrupted_tests > 0)
- printf(", %d interrupted)", number_of_interrupted_tests);
-
- printf(")\n\n");
-
-
- total_of_tests += number_of_tests;
- total_of_failed_tests += number_of_failed_tests;
- total_of_interrupted_tests += number_of_interrupted_tests;
- total_of_successeded_tests += number_of_successeded_tests;
- }
-
- /* suites */
-
- total_of_units = number_of_units;
-
- total_of_failed_suites = total_of_successeded_suites = total_of_interrupted_suites = 0;
-
- total_of_suites = vector_get_size(unit->suites);
-
- for(k = 0; k < total_of_suites; k++)
- {
- suite = vector_get_at(unit->suites, k);
-
- display_title(suite->description);
-
- number_of_tests_of_suite = number_of_interrupted_tests_of_suite = number_of_failed_tests_of_suite = number_of_successeded_tests_of_suite = 0;
-
- number_of_interrupted_units = number_of_failed_units = number_of_successeded_units = 0;
-
- number_of_units = vector_get_size(suite->includes);
-
- for(i = 0; i < number_of_units; i++)
- {
- number_of_interrupted_tests = number_of_failed_tests = number_of_successeded_tests = 0;
-
- number_of_tests = vector_get_size(include->commands);
-
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command = vector_get_at(include->commands, j);
-
- if(command->status == cs_interrupted)
- number_of_interrupted_tests++;
- else if(command->status == cs_failed)
- number_of_failed_tests++;
- else if(command->status == cs_successeded)
- number_of_successeded_tests++;
-
- }
-
-
- include = vector_get_at(suite->includes, i);
- asprintf(&p," Unit: %s ............................................................................", include->description ? include->description : include->fstream->name);
-
- p[70] = '\0';
- printf("%s", p);
- free(p);
-
- if(number_of_failed_tests > 0)
- {
- number_of_failed_units++;
- printf(".. failed\n");
- }
- else if(number_of_interrupted_tests > 0)
- {
- number_of_interrupted_units++;
- printf("interrupt\n");
- }
- else
- {
- number_of_successeded_units++;
- printf(".... ..ok\n");
- }
-
- number_of_interrupted_tests_of_suite += number_of_interrupted_tests;
- number_of_failed_tests_of_suite += number_of_failed_tests;
- number_of_successeded_tests_of_suite += number_of_successeded_tests;
-
- number_of_tests_of_suite += number_of_tests;
-
- total_of_tests += number_of_tests;
- total_of_failed_tests += number_of_failed_tests;
- total_of_interrupted_tests += number_of_interrupted_tests;
- total_of_successeded_tests += number_of_successeded_tests;
-
- if(want_detail_summary)
- {
- for(j = 0; j < vector_get_size(include->commands); j++)
- {
- command = vector_get_at(include->commands, j);
-
- printf(" %s: %s [%s]\n",
- command->status == cs_interrupted ? "INTR "
- : command->status == cs_failed ? "FAILED"
- : command->status == cs_successeded ? "PASS "
- : "UNKNWN",
- command->context->command_line,
- command->context->line);
-
- command_display_status(command);
-
- }
-
-
- }
-
- }
-
-
-
- printf(" =====================================================================%s\n",
- number_of_failed_tests_of_suite ? "== FAILED": number_of_interrupted_tests_of_suite ? "==== INTR" : "====== OK");
-
- if(number_of_failed_tests_of_suite > 0)
- total_of_failed_suites++;
- else if(number_of_interrupted_tests_of_suite)
- total_of_interrupted_suites++;
- else
- total_of_successeded_suites++;
-
- total_of_failed_units += number_of_failed_units;
- total_of_interrupted_units += number_of_interrupted_units;
- total_of_successeded_units += number_of_successeded_units;
-
- total_of_units += number_of_units;
-
- printf(" Summary: Unit(s): %.0f%% ok (%d unit(s): %d ok",
- (number_of_units ? (1-((double)number_of_failed_units + (double)number_of_interrupted_units)/(double)number_of_units)*100.0 : 100.0),
- number_of_units, number_of_successeded_units);
-
- if(number_of_failed_units > 0)
- printf(", %d failed", number_of_failed_units);
-
- if(number_of_interrupted_units > 0)
- printf(", %d interrupted)", number_of_interrupted_units);
-
- printf(")\n");
-
- printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
- (number_of_tests_of_suite ? (1-((double)number_of_failed_tests_of_suite + (double)number_of_interrupted_tests_of_suite)/(double)number_of_tests_of_suite)*100.0 : 100.0),
- number_of_tests_of_suite, number_of_successeded_tests_of_suite);
-
- if(number_of_failed_tests_of_suite > 0)
- printf(", %d failed", number_of_failed_tests_of_suite);
-
- if(number_of_interrupted_tests_of_suite > 0)
- printf(", %d interrupted)", number_of_interrupted_tests_of_suite);
-
- printf(")\n\n");
- }
-
- printf(" TOTAL : Suite(s): %.0f%% ok (%d suite(s): %d ok",
- (total_of_suites ? (1-((double)total_of_failed_suites + (double)total_of_interrupted_suites)/(double)total_of_suites)*100.0 : 100.0),
- total_of_suites, total_of_successeded_suites);
-
- if(total_of_failed_suites > 0)
- printf(", %d failed", total_of_failed_suites);
-
- if(total_of_interrupted_suites > 0)
- printf(", %d interrupted)", total_of_interrupted_suites);
-
- printf(")\n");
-
- printf(" Unit(s): %.0f%% ok (%d unit(s): %d ok",
- (total_of_units ? (1-((double)total_of_failed_units + (double)total_of_interrupted_units)/(double)total_of_units)*100.0 : 100.0),
- total_of_units, total_of_successeded_units);
-
- if(total_of_failed_units > 0)
- printf(", %d failed", total_of_failed_units);
-
- if(total_of_interrupted_units > 0)
- printf(", %d interrupted)", total_of_interrupted_units);
-
- printf(")\n");
-
- printf(" Test(s): %.0f%% ok (%d test(s): %d ok",
- (total_of_tests ? (1-((double)total_of_failed_tests + (double)total_of_interrupted_tests)/(double)total_of_tests)*100.0 : 100.0),
- total_of_tests, total_of_successeded_tests);
-
- if(total_of_failed_tests > 0)
- printf(", %d failed", total_of_failed_tests);
-
- if(total_of_interrupted_tests > 0)
- printf(", %d interrupted)", total_of_interrupted_tests);
-
- printf(")\n\n");
-
-
- if(unit->interrupted)
- unit->runner->total_of_interrupted_units++;
- else if(total_of_failed_tests > 0)
- unit->runner->total_of_failed_units++;
- else
- unit->runner->total_of_successeded_units++;
-
-
- unit->runner->total_of_tests += total_of_tests;
- unit->runner->total_of_failed_tests += total_of_failed_tests;
- unit->runner->total_of_successeded_tests += total_of_successeded_tests;
- unit->runner->total_of_interrupted_tests += total_of_interrupted_tests;
-
-
- unit->runner->total_of_units += total_of_units + 1;
- unit->runner->total_of_successeded_units += total_of_successeded_units;
- unit->runner->total_of_failed_units += total_of_failed_units;
- unit->runner->total_of_interrupted_units += total_of_interrupted_units;
-
-
- unit->runner->total_of_suites += total_of_suites;
- unit->runner->total_of_successeded_suites += total_of_successeded_suites;
- unit->runner->total_of_failed_suites += total_of_failed_suites;
- unit->runner->total_of_interrupted_suites += total_of_interrupted_suites;
-
-
-
-}
-
-
-
-
-void
-unit_handle_include(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* file_name, const char* description)
-{
- directory_t dir;
- char* prev_directory = NULL;
- fstream_t fstream = NULL;
- struct stat buffer = {0};
-
- if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
- {
- /* the file is in the current directory */
-
- fstream = fstream_new(getcwd(NULL, 0), file_name);
- fstream_open(fstream);
- }
- /* the file to include is not in the current directory, check if it is in a include directory */
- else
- {
- prev_directory = getcwd(NULL, 0);
-
- vector_rewind(include_dirs);
-
- while((dir = vector_get(include_dirs)))
- {
- chdir(dir->name);
-
- if(!stat(file_name, &buffer) && S_ISREG(buffer.st_mode))
- {
- fstream = fstream_new(dir->name, file_name);
- fstream_open(fstream);
- break;
- }
-
-
- vector_move_next(include_dirs);
- }
-
- chdir(prev_directory);
- free(prev_directory);
- }
-
-
-
- /* the file to include is not found handle the failure */
- if(!fstream)
- {
- exit_code = EINCLUDENOTFOUND;
- ERROR1("Include file %s not found",file_name);
- unit_handle_failure(unit);
- }
- else
- {
-
- if(!unit->running_suite)
- {/* it's the unit of a suite */
- unit_t include = unit_new(unit->runner,unit->root, unit, fstream);
-
- include->mutex = unit->root->mutex;
-
- if(description)
- include->description = strdup(description);
-
- vector_push_back(unit->includes, include);
-
- fstream_parse(fstream, include, mutex);
- }
- else
- {/* it's a include */
- unit_t owner = vector_get_back(unit->suites);
- unit_t include = unit_new(unit->runner,unit->root, owner, fstream);
-
- include->mutex = unit->root->mutex;
-
- if(description)
- include->description = strdup(description);
-
- vector_push_back(owner->includes, include);
-
- fstream_parse(fstream, include, mutex);
- }
- }
-}
-
-void
-unit_handle_suite(unit_t unit, context_t context, xbt_os_mutex_t mutex, const char* description)
-{
- if(unit->running_suite)
- {
- exit_code = ESYNTAX;
- unit_handle_failure(unit);
- }
- else
- {
- unit_t suite = unit_new(unit->runner, unit->root, unit, NULL);
- suite->is_suite = 1;
- suite->description = strdup(description);
- vector_push_back(unit->suites, suite);
- unit->running_suite = 1;
- }
-}
-
-int
-unit_reset(unit_t unit)
-{
- fseek(unit->fstream->stream,0L, SEEK_SET);
- unit->parsed = 0;
- unit->number_of_commands = 0;
-
- return 0;
-}
+++ /dev/null
-#include <units.h>
-#include <unit.h>
-#include <fstreams.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-units_t
-units_new(runner_t runner, fstreams_t fstreams)
-{
- register fstream_t fstream;
-
- units_t units = xbt_new0(s_units_t, 1);
-
- if(!(units->items = vector_new(fstreams_get_size(fstreams), unit_free)))
- {
- free(units);
- return NULL;
- }
-
-
- vector_rewind(fstreams->items);
-
- while((fstream = vector_get(fstreams->items)))
- {
- if(vector_push_back(units->items, unit_new(runner, NULL, NULL, fstream)))
- {
- vector_free(&(units->items));
- free(units);
- return NULL;
- }
-
- vector_move_next(fstreams->items);
- }
-
- return units;
-}
-
-
-int
-units_is_empty(units_t units)
-{
- if(!units)
- {
- errno = EINVAL;
- return 0;
- }
-
- return vector_is_empty(units->items);
-}
-
-int
-units_get_size(units_t units)
-{
- if(!units)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector_get_size(units->items);
-}
-
-
-int
-units_run_all(units_t units, xbt_os_mutex_t mutex)
-{
- register unit_t unit;
-
- if(!units)
- return EINVAL;
-
- if(vector_is_empty(units->items))
- return EAGAIN;
-
- /* move the cursor at the begining of the vector */
- vector_rewind(units->items);
-
- /* run all the units */
- while((unit = vector_get(units->items)))
- {
- unit_run(unit, mutex);
- vector_move_next(units->items);
-
- }
-
- return 0;
-
-}
-
-int
-units_join_all(units_t units)
-{
- register unit_t unit;
-
- if(!units)
- return EINVAL;
-
- if(vector_is_empty(units->items))
- return EAGAIN;
-
- /* move the cursor at the begining of the vector */
- vector_rewind(units->items);
-
- /* run all the units */
- while((unit = vector_get(units->items)))
- {
- if(unit->thread)
- xbt_os_thread_join(unit->thread, NULL);
-
- vector_move_next(units->items);
- }
-
- return 0;
-}
-
-int
-units_interrupt_all(units_t units)
-{
- register unit_t unit;
-
- if(!units)
- return EINVAL;
-
- if(vector_is_empty(units->items))
- return EAGAIN;
-
- /* move the cursor at the begining of the vector */
- vector_rewind(units->items);
-
- /* run all the units */
- while((unit = vector_get(units->items)))
- {
- if(!(unit->successeded) && !(unit->interrupted))
- unit_interrupt(unit);
-
- vector_move_next(units->items);
- }
-
- return 0;
-}
-
-int
-units_verbose(units_t units)
-{
- register unit_t unit;
-
- if(!units)
- return EINVAL;
-
- if(vector_is_empty(units->items))
- return EAGAIN;
-
- /* move the cursor at the begining of the vector */
- vector_rewind(units->items);
-
- /* run all the units */
- while((unit = vector_get(units->items)))
- {
- unit_verbose(unit);
- vector_move_next(units->items);
- }
-
- return 0;
-
-}
-
-int
-units_reset_all(units_t units)
-{
- register unit_t unit;
-
- if(!units)
- return EINVAL;
-
- if(vector_is_empty(units->items))
- return EAGAIN;
-
- /* move the cursor at the begining of the vector */
- vector_rewind(units->items);
-
- /* run all the units */
- while((unit = vector_get(units->items)))
- {
- unit_reset(unit);
- vector_move_next(units->items);
- }
-
- return 0;
-}
-
-int
-units_free(void** unitsptr)
-{
- int rv;
-
- if(!(*unitsptr))
- return EINVAL;
-
- if((rv = vector_free(&((*((units_t*)unitsptr))->items))))
- return rv;
-
- free(*unitsptr);
- *unitsptr = NULL;
-
- return 0;
-}
-
+++ /dev/null
-#include <variable.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-variable_t
-variable_new(const char* name, const char* val)
-{
- variable_t variable;
-
- if(!name || !val)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(variable = (variable_t)calloc(1, sizeof(s_variable_t))))
- return NULL;
-
- variable->name = strdup(name);
- variable->val = strdup(val);
- variable->used = 0;
- variable->env = 0;
- variable->err = 0;
-
- return variable;
-
-}
-
-int
-variable_free(variable_t* variableptr)
-{
- if(!(*variableptr))
- return EINVAL;
-
- free((*((variable_t*)(variableptr)))->name);
- free((*((variable_t*)(variableptr)))->val);
-
- free(*variableptr);
-
- *variableptr = NULL;
- return 0;
-}
-
-
-int
-variable_is_used(variable_t variable)
-{
- if(!variable)
- {
- errno = EINVAL;
- return 0;
- }
-
- return variable->used;
-}
-
-
-int
-variable_set_used(variable_t variable)
-{
- if(!variable)
- return EINVAL;
-
- variable->used = 1;
-
- return 0;
-}
+++ /dev/null
-#include <com.h>
\ No newline at end of file
+++ /dev/null
-
-#include <vector.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdio.h>
-
-#ifdef _MSC_VER
-#define inline _inline
-#endif
-
-static inline int
-resize(vector_t vector)
-{
- return vector_reserve(vector, !(vector->capacity) ? 1 : (vector->size) << 1);
-}
-
-static inline int
-move(vector_t vector, int dst,int src, int size)
-{
- return (NULL != memmove(vector->items + dst, vector->items + src,size * sizeof(void*)));
-}
-
-vector_t
-vector_new(int capacity, fn_finalize_t fn_finalize)
-{
- vector_t vector;
-
- if(capacity < 0)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!(vector = (vector_t)calloc(1,sizeof(s_vector_t))))
- return NULL;
-
- if(capacity)
- {
- if(!(vector->items = (void**)calloc(capacity,sizeof(void*))))
- {
- free(vector);
- return NULL;
- }
-
- vector->capacity = capacity;
- }
-
- vector->fn_finalize = fn_finalize;
- vector->pos = -1;
- return vector;
-}
-
-int
-vector_clear(vector_t vector)
-{
- int rv;
-
- if(!vector)
- return EINVAL;
-
- if(!vector->size)
- return 0;
-
- if(vector->fn_finalize)
- {
- int size = vector->size;
- fn_finalize_t fn_finalize = vector->fn_finalize;
- void** items = vector->items;
- register int pos;
-
- for(pos = 0; pos < size; pos++)
- {
- if((rv = (*(fn_finalize))(&(items[pos]))))
- return rv;
- else
- vector->size--;
- }
- }
- else
- {
- vector->size = 0;
- }
-
- vector->pos = -1;
-
- return 0;
-}
-
-int
-vector_free(vector_t* vector_ptr)
-{
- int rv;
-
- if(!(*vector_ptr))
- return EINVAL;
-
- if((rv = vector_clear(*vector_ptr)))
- return rv;
-
- free(*vector_ptr);
- *vector_ptr = NULL;
-
- return 0;
-}
-
-int
-vector_is_empty(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- return !vector->size;
-}
-
-int
-vector_get_size(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector->size;
-}
-
-void*
-vector_get_front(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return vector->items[0];
-}
-
-void*
-vector_get_back(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- return vector->items[vector->size - 1];
-}
-
-int
-vector_get_capacity_available(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
- return (vector->capacity - vector->size);
-}
-
-int
-vector_push_back(vector_t vector, void* item)
-{
- int rv;
-
- if(!vector || !item)
- return EINVAL;
-
- /* if all capacity is used, resize the vector */
- if(vector->capacity <= vector->size)
- {
- if((rv = resize(vector)))
- return rv;
- }
-
- /* increment the item count and push the new item at the end of the vector */
- vector->items[++(vector->size) - 1] = item;
-
- vector->pos = -1;
-
-
- return 0;
-}
-
-void*
-vector_pop_back(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- vector->pos = -1;
-
- return vector->items[(vector->size)-- - 1];
-}
-
-int
-vector_get_upper_bound(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return -1;
- }
-
- return (vector->size - 1);
-}
-
-void*
-vector_set_at(vector_t vector, int pos, void* item)
-{
- void* prev_item;
-
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
- if((pos < 0) || (pos >= vector->size))
- {
- errno = ERANGE;
- return NULL;
- }
-
- prev_item = vector->items[pos];
- vector->items[pos] = item;
- return prev_item;
-}
-
-int
-vector_insert(vector_t vector, int pos, void* item)
-{
- int rv;
-
- if(!vector)
- return EINVAL;
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- if((pos < 0) || (pos >= vector->size))
- {
- errno = ERANGE;
- return 0;
- }
-
- if(vector->size >= vector->capacity)
- {
- if((rv = resize(vector)))
- return rv;
- }
-
- if(vector->size)
- {
- if(!move(vector, pos + 1, pos, vector->size - pos))
- return errno;
- }
-
- vector->size++;
- vector->items[pos] = item;
- vector->pos = -1;
-
- return 0;
-}
-
-int
-vector_erase_at(vector_t vector, int pos)
-{
- int rv;
-
- if(!vector)
- return EINVAL;
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- if((pos < 0) || (pos >= vector->size))
- {
- errno = ERANGE;
- return 0;
- }
-
- if(vector->fn_finalize)
- {
- if((rv = (*(vector->fn_finalize))(&(vector->items[pos]))))
- return rv;
- }
-
- if(pos != (vector->size - 1))
- {
- if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
- return errno;
- }
-
- vector->size--;
- vector->pos = -1;
-
- return 0;
-}
-
-int
-vector_erase(vector_t vector, void* item)
-{
- int pos, rv;
-
- if(!vector || !item)
- return EINVAL;
-
- if(!vector->size)
- return EAGAIN;
-
- if(-1 == (pos = vector_search(vector,item)))
- return errno;
-
- if(vector->fn_finalize)
- {
- if((rv = (*(vector->fn_finalize))(&item)))
- return rv;
- }
-
- if(pos != (vector->size - 1))
- if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
- return errno;
-
- vector->size--;
-
- vector->pos = -1;
-
- return 0;
-}
-
-int
-vector_erase_range(vector_t vector, int first, int last)
-{
- register int width;
- int rv;
-
- if(!vector || first >= last)
- return EINVAL;
-
- if(vector->size < 2)
- return EAGAIN;
-
- if((first < 0) || (last < 0) || (last >= vector->size))
- return ERANGE;
-
- width = (last - first) + 1;
-
- while(width--)
- {
- if((rv = vector_erase_at(vector,first)))
- return rv;
- }
-
- return 0;
-}
-
-int
-vector_search(vector_t vector, void* item)
-{
- register int pos;
- void** items;
- int size;
-
- if(!vector || !item)
- {
- errno = EINVAL;
- return -1;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return -1;
- }
-
- vector = (vector_t)vector;
-
- items = vector->items;
- size = vector->size;
-
- for(pos = 0 ; pos < size; pos++)
- {
- if(items[pos] == item)
- return pos;
- }
-
- errno = ESRCH;
- return -1;
-}
-
-int
-vector_remove(vector_t vector, void* item)
-{
- int pos;
-
- if(!vector || !item)
- return EINVAL;
-
- if(!vector->size)
- return EAGAIN;
-
- if(-1 == (pos = vector_search(vector,item)))
- return errno;
-
- if(pos != (vector->size - 1))
- if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
- return errno;
-
- vector->size--;
-
- vector->pos = -1;
-
- return 0;
-}
-
-int
-vector_assign(vector_t dst,vector_t src)
-{
- register int pos;
- int size;
- void** items;
- int rv;
-
-
- if(!dst || !src ||(dst == src))
- return EINVAL;
-
- if(!src->size)
- return EAGAIN;
-
- size = src->size;
-
- /* if the destination vector has not enough capacity resize it */
- if(size > dst->capacity)
- {
- if((rv = vector_reserve(dst, size - dst->capacity)))
- return rv;
- }
-
- /* clear the destination vector */
- if((rv = vector_clear(dst)))
- return rv;
-
- dst->fn_finalize = NULL;
-
- items = src->items;
-
- /* file the destination vector */
- for(pos = 0; pos < size; pos++)
- if((rv = vector_push_back(dst,items[pos])))
- return rv;
-
- dst->pos = -1;
-
- return 0;
-}
-
-int
-vector_get_capacity(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
- return vector->capacity;
-}
-
-int
-vector_equals(vector_t first, vector_t second)
-{
- register int pos;
- int size;
- void** __first, ** __second;
-
-
- if(!first || !second || (first == second))
- {
- errno = EINVAL;
- return 0;
- }
-
- if(first->size != second->size)
- return 0;
-
- size = first->size;
- __first = first->items;
- __second = second->items;
-
- for(pos = 0; pos < size; pos++)
- {
- if(__first[pos] != __second[pos])
- return 0;
- }
-
- return 1;
-}
-
-vector_t
-vector_clone(vector_t vector)
-{
- int size;
- register int pos;
- void** dst,** src;
- vector_t clone;
-
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- clone = vector_new(vector->capacity,NULL);
-
- if(!clone)
- return NULL;
-
- size = vector->size;
- src = vector->items;
- dst = clone->items;
-
- for(pos = 0; pos < size; pos++)
- dst[pos] = src[pos];
-
- clone->size = size;
-
- return clone;
-}
-
-int
-vector_contains(vector_t vector,void* item)
-{
- if(!vector || !item)
- {
- errno = EINVAL;
- return 0;
- }
-
- return (-1 != vector_search(vector,item));
-}
-
-int
-vector_swap(vector_t first,vector_t second)
-{
- s_vector_t tmp;
-
- if(!first || !second)
- return EINVAL;
-
- /* save the content or first */
- tmp = *first;
-
- /* copy second in first */
- if(!memcpy(first, second, sizeof(s_vector_t)))
- return 0;
-
- /* copy tmp in first */
- if(!memcpy(second, &tmp, sizeof(s_vector_t)))
- {
- *first = tmp;
- return 0;
- }
-
- return 1;
-}
-
-int
-vector_reserve(vector_t vector, int size)
-{
- void** items;
-
- if(!vector || (size < 0))
- return EINVAL;
-
- if(vector->capacity >= size)
- return EAGAIN;
-
- if(!(items = (void**)realloc(vector->items, size * sizeof(void*))))
- return errno;
-
-
- vector->capacity = size;
- vector->items = items;
-
- return 0;
-}
-
-int
-vector_is_autodelete(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- return NULL != vector->fn_finalize;
-}
-
-int
-vector_has_capacity_available(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- return (vector->capacity > vector->size);
-}
-
-int
-vector_is_full(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
-
- return (vector->capacity == vector->size);
-}
-
-int
-vector_get_max_index(vector_t vector)
-{
-
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
-
- return vector->size - 1;
-}
-
-void*
-vector_get(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
- return vector->items[vector->pos];
-}
-
-void*
-vector_get_at(vector_t vector, int pos)
-{
- if(!vector)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(pos < 0 || pos >= vector->size)
- {
- errno = ERANGE;
- return NULL;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return NULL;
- }
-
-
- return vector->items[pos];
-}
-
-int
-vector_getpos(vector_t vector, int* pos)
-{
-
- if(!vector || !pos)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- *pos = vector->pos;
- return 1;
-}
-
-int
-vector_move_next(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(vector->pos < (vector->size - 1))
- {
- vector->pos++;
- return 1;
- }
-
- vector->pos = -1;
- errno = ERANGE;
- return 0;
-}
-
-int
-vector_move_prev(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return 0;
- }
-
- if(vector->pos > 0)
- {
- vector->pos--;
- return 1;
- }
-
- vector->pos = -1;
- errno = ERANGE;
- return 0;
-
-}
-
-int
-vector_rewind(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- vector->pos = 0;
-
- return 1;
-}
-
-static int
-seek_set(vector_t vector, int offset)
-{
- if(offset > vector->size)
- return EINVAL;
-
- vector_rewind(vector);
-
- while(offset--)
- vector_move_next(vector);
-
- return 0;
-}
-
-static int
-seek_end(vector_t vector, int offset)
-{
- if(offset > vector->size)
- return EINVAL;
-
- vector_unwind(vector);
-
- while(offset--)
- vector_move_prev(vector);
-
- return 0;
-}
-
-
-static int
-seek_cur(vector_t vector, int offset)
-{
- if(vector->pos == 0)
- {
- /* we are at the begin of the vector */
- seek_set(vector, offset);
- }
- else if(vector->pos == vector->size - 1)
- {
- /* we are at the end of the vector */
- seek_end(vector, offset);
- }
- else
- {
- if(offset > (vector->size - vector->pos + 1))
- return EINVAL;
-
- while(offset--)
- vector_move_next(vector);
-
- }
-
- return 0;
-}
-
-int
-vector_seek(vector_t vector, int offset, int whence)
-{
- if(!vector)
- return EINVAL;
-
- if(!vector->size)
- return EAGAIN;
-
- switch(whence)
- {
- case SEEK_SET :
- return seek_set(vector, offset);
-
- case SEEK_CUR :
- return seek_cur(vector, offset);
-
- case SEEK_END :
- return seek_end(vector, offset);
-
- }
-
- return EINVAL;
-}
-
-void*
-vector_set(vector_t vector, void* item)
-{
- void* prev_item;
-
- if(!vector || !item)
- {
- errno = EINVAL;
- return NULL;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return NULL;
- }
-
- prev_item = vector->items[vector->pos];
- vector->items[vector->pos] = item;
-
- return prev_item;
-}
-
-int
-vector_setpos(vector_t vector, int pos)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(pos < 0 || pos >= vector->size)
- {
- errno = ERANGE;
- return 0;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- vector->pos = pos;
- return 1;
-}
-
-int
-vector_tell(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return -1;
- }
-
- if(!vector->size || (-1 == vector->pos))
- {
- errno = EAGAIN;
- return -1;
- }
-
- return vector->pos;
-}
-
-int
-vector_unwind(vector_t vector)
-{
- if(!vector)
- {
- errno = EINVAL;
- return 0;
- }
-
- if(!vector->size)
- {
- errno = EAGAIN;
- return 0;
- }
-
- vector->pos = vector->size - 1;
- return 1;
-}
+++ /dev/null
-#include <writer.h>
-#include <command.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void*
-writer_start_routine(void* p);
-
-writer_t
-writer_new(command_t command)
-{
- writer_t writer = xbt_new0(s_writer_t, 1);
-
- writer->thread = NULL;
- writer->command = command;
- writer->written = xbt_os_sem_init(0);
- writer->can_write = xbt_os_sem_init(0);
-
- writer->done = 0;
-
- return writer;
-}
-
-void
-writer_free(writer_t* writer)
-{
-
- /*xbt_os_sem_destroy((*writer)->started);
- xbt_os_sem_destroy((*writer)->can_write);*/
-
- free(*writer);
- *writer = NULL;
-}
-
-void
-writer_write(writer_t writer)
-{
- writer->thread = xbt_os_thread_create("", writer_start_routine, writer);
-}
-
-#ifdef WIN32
-static void*
-writer_start_routine(void* p)
-{
- writer_t writer = (writer_t)p;
- command_t command = writer->command;
-
- char* input = (char*)(command->context->input->data);
-
- DWORD number_of_bytes_to_write = command->context->input->used;
- DWORD number_of_bytes_written = 0;
-
-
- while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)
- {
- if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))
- {
- if(GetLastError() == ERROR_NO_DATA)
- writer->broken_pipe = 1;
- else
- writer->failed = 1;
-
- }
- else
- {
- input += number_of_bytes_written;
- number_of_bytes_to_write -= number_of_bytes_written;
- }
- }
-
- command->context->input->data[0]='\0';
- command->context->input->used=0;
-
- if(writer->failed && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- exit_code = EWRITE;
- command_handle_failure(command, csr_write_failure);
- }
- /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- command_handle_failure(command, csr_write_pipe_broken);
- }*/
-
-
- return NULL;
-}
-#else
-/*static void*
-writer_start_routine(void* p)
-{
- writer_t writer = (writer_t)p;
- command_t command = writer->command;
- int number_of_bytes_written = 0;
- int number_of_bytes_to_write = command->context->input->used;
- char* input = (char*)(command->context->input->data);
- int got;
-
- xbt_os_sem_release(writer->started);
-
-
-
- while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && (number_of_bytes_written < number_of_bytes_to_write))
- {
- got = write(writer->command->stdin_fd, input + number_of_bytes_written, number_of_bytes_to_write - number_of_bytes_written);
-
- if(got > 0)
- number_of_bytes_written += got;
-
- if(got < 0)
- {
- if(errno == EPIPE)
- {
- writer->broken_pipe = 1;
- }
- else if(errno != EINTR && errno != EAGAIN && errno != EPIPE)
- {
- writer->failed = 1;
- }
- }
-
- if(got <= 0)
- usleep(100);
- }
-
- command->context->input->data[0]='\0';
- command->context->input->used=0;
-
- if(writer->failed && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- exit_code = EWRITE;
- command_handle_failure(command, csr_write_failure);
- }
- else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- exit_code = EWRITEPIPE;
- command_handle_failure(command, csr_write_pipe_broken);
- }
-
-
- close(command->stdin_fd);
- command->stdin_fd = INDEFINITE_FD;
-
- return NULL;
-}*/
-
-static void*
-writer_start_routine(void* p)
-{
- writer_t writer = (writer_t)p;
- command_t command = writer->command;
- int number_of_bytes_to_write = command->context->input->used;
- char* input = (char*)(command->context->input->data);
- int got;
- int released = 0;
-
-
- xbt_os_sem_acquire(writer->can_write);
-
-
- while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)
- {
- got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;
- got = write(writer->command->stdin_fd, input, got );
-
- if(got < 0)
- {
- if(EINTR == errno)
- continue;
-
- else if(EAGAIN == errno)
- {/* the pipe is full */
- if(!released)
- {
- xbt_os_sem_release(writer->written);
- released = 1;
- }
-
- continue;
- }
- else if(EPIPE == errno)
- {
- writer->broken_pipe = 1;
- break;
- }
- else
- {
- writer->failed = 1;
- break;
- }
-
- }
-
- number_of_bytes_to_write -= got;
- input += got;
-
- if(got == 0)
- xbt_os_thread_yield();
-
- }
-
- if(!released)
- {
- xbt_os_sem_release(writer->written);
- released = 1;
- }
-
-
- close(command->stdin_fd);
- command->stdin_fd = INDEFINITE_FD;
-
- command->context->input->data[0]='\0';
- command->context->input->used=0;
-
- if(writer->failed && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- exit_code = EWRITE;
- command_handle_failure(command, csr_write_failure);
- }
- else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
- {
- command_kill(command);
- exit_code = EWRITEPIPE;
- command_handle_failure(command, csr_write_pipe_broken);
- }
-
- writer->done = 1;
-
- return NULL;
-
-}
-
-#endif
-void
-writer_wait(writer_t writer)
-{
- xbt_os_thread_join(writer->thread, NULL);
-
-}
+++ /dev/null
-#! ./tesh
-
-# This suite show how to use the suite concept. A suite is specified
-# by the metacommand suite have a description and contains some units.
-
-# declare and define the variable dir
-! testdir=temp_testdir
-
-# delete the temp_testdir if it already exists
-$ rm -rf $testdir
-
-# create the tempory test directory
-$ mkdir $testdir
-
-# enter in the tempory test directory
-$ cd $testdir
-
-$ cd ..
-
-$ rm -rf $testdir
-
-# this is the first suite
-! suite first suite
-! include set-timeout.tesh display how to use the timeout metacommand
-! include set-signal.tesh display how to use the signal metacommand
-# this unit has no description (the file name of the unit will be used)
-! include background.tesh
-
-# this is the second suite
-! suite second suite
-! include cd.tesh
-! include basic.tesh
-! include bg-basic.tesh like basic but used backgrounded commands
-
-# a simple inclusion
-! include catch-return.tesh
-
-# declare and define some variables
-! description=the description of the unit
-! arg=hello tesh
-! rv=0
-! t=5
-! bin=./var-sample
-! expect return $rv
-! timeout $t
-> $arg
-$ $bin "$arg"
-