From ddd84f0fb297cb1070c8a9bb0e65681e64b0383f Mon Sep 17 00:00:00 2001 From: cherierm Date: Tue, 19 Dec 2006 16:28:59 +0000 Subject: [PATCH] stream concept implementation git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3013 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- win32_test_app/src/TStream.c | 629 +++++++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 win32_test_app/src/TStream.c diff --git a/win32_test_app/src/TStream.c b/win32_test_app/src/TStream.c new file mode 100644 index 0000000000..a395c03776 --- /dev/null +++ b/win32_test_app/src/TStream.c @@ -0,0 +1,629 @@ +#include + +extern const char* TOKENS = "$<>#!p&"; + +CRITICAL_SECTION cs; + +const char * __metacommandlist[ ] = +{ + "set timeout ", + "enable output checking", + "disable output checking", + "enable post output checking", + "disable post output checking", + "expect exit code ", + "export ", + "unset ", + "create console", + "create no console", + "enable exit code checking", + "disable exit code checking", + "command line ", + NULL +}; + +/* + * Create a new s_Stream struct and return + * a pointer to self + */ + +Stream_t Stream_new(void) +{ + Stream_t ptr = (Stream_t)calloc(1,sizeof(s_Stream_t)); + + if(NULL == ptr) + { + setErrno(E_STREAM_ALLOCATION_FAILED); + Stream_free(ptr); + } + + memset(&cs,0,sizeof(CRITICAL_SECTION)) ; + InitializeCriticalSection(&cs); + + ptr->line = NULL; + ptr->line_number = 0; + + return ptr; +} + +/* + * Returns true if the current text line is blank. + */ +bool Stream_lineIsBlank(Stream_t stream) +{ + size_t i = 0; + char* p = (char*)stream->line; + + while(p[i] != '\n') + { + if(!Stream_isBlankChar(p[i])) + return false; + i++; + + } + + return true; +} + +/* + * Return true if the caracter is space or tab. + */ +bool Stream_isBlankChar(char ch) +{ + return ((ch ==' ') || ch == ('\t')); +} + +/* + * Return E_SUCCESS if the file is valid. + * Otherwise the fuction returns E_INVALID_FILE. + */ +errno_t Stream_isValidFile(const char* file_name) +{ + WIN32_FIND_DATA wfd ={0}; + HANDLE hFile = FindFirstFile(file_name,&wfd); + + if(INVALID_HANDLE_VALUE == hFile) + return E_FILE_NOT_FOUND; + + FindClose(hFile); + return E_SUCCESS; +} + +/* + * Return E_SUCCESS is the open file operation succeeded. + * Otherwise the functions returns E_OPEN_FILE_FAILED. + */ +errno_t Stream_openFile(Stream_t ptr,const char* file_name) +{ + ptr->file = fopen(file_name,"r"); + + if(NULL == ptr->file) + { + setErrno(E_OPEN_FILE_FAILED); + return getErrno(); + } + + return E_SUCCESS; +} + +/* + * This function reads an entire line, storing + * the address of the buffer containing the text into + * *dest. + */ +ssize_t Stream_getLine(Stream_t stream) +{ + size_t capacity_available; /* capacity available in the buffer */ + char* pos; /* read operation position */ + ssize_t size; /* the size of the text line (minus the 0 terminal */ + static size_t len = 0; + register int ch; /* the current character */ + FILE* file = stream->file; + + if(NULL == file) + { + setErrno(E_INVALID_FILE_Stream); + return -1; + } + + if(NULL == stream->line) + { + len = DEFAULT_ALLOC_SIZE; + stream->line = (char*)calloc(1,len); + + if (NULL == stream->line) + { + setErrno(E_STREAM_LINE_ALLOCATION_FAILED); + return -1; + } + } + else + { + memset(stream->line,0,len); + } + + capacity_available = len ; + pos = stream->line; + + while(true) + { + ch = getc(file); + + /* un byte for the next char and one byte for the zero terminal. */ + if (capacity_available < 2) + { + if (len > DEFAULT_ALLOC_SIZE) + len = len << 1; + else + len += DEFAULT_ALLOC_SIZE; + + capacity_available =stream->line + len - pos; + stream->line = realloc (stream->line,len); + + if (NULL ==stream->line) + { + setErrno(E_STREAM_LINE_REALLOCATION_FAILED); + return -1; + } + + pos = stream->line + len - capacity_available ; + } + + if(ferror(file)) + { + /* file error exit on error*/ + setErrno(E_STREAM_ERROR); + return -1; + } + + if((EOF == ch)) + { + /* Empty file */ + if(!strlen(stream->line) && !stream->line_number) + { + setErrno(E_STREAM_EMPTY); + return -1; + } + /* end of file */ + else if(!strlen(stream->line) && stream->line_number) + { + return -1; + } + + break; + } + + *pos++ = ch; + capacity_available--; + + /* we have a line, exit loop */ + if (ch == '\n') + break; + } + + /* append the zero terminal */ + + *pos = '\0'; + size = pos - stream->line; + + stream->line_number++; + + /* size of texte line without zero terminal */ + return size; +} + + +/* + * Free a s_Stream. + */ + +void Stream_free(Stream_t ptr) +{ + if(NULL == ptr) + return; + + if((NULL !=ptr->file) && (stdin != ptr->file)) + fclose(ptr->file); + + if(NULL != ptr->line) + free(ptr->line); + + DeleteCriticalSection(&cs); + + free(ptr); +} + +/* + * Return true if the current line is a comment. + * Otherwise the functions returns false. + */ +bool Stream_lineIsComment(Stream_t stream) +{ + return stream->line[0] == '#'; +} + +/* Return true if the current line contains a invalide token. + * Otherwise, the function returns false. + */ +bool Stream_lineContainsInvalidToken(Stream_t stream) +{ + if(strchr(TOKENS,stream->line[0]) == NULL) + { + Stream_printLine(stream,invalid_token_line_type); + setErrno(E_INVALID_TOKEN); + return true; + } + + return false; +} + +/* + * Return true if the text line is a meta command. + * Otherwise, the functions returns false. + */ +bool Stream_lineIsMetacommand(Stream_t stream) +{ + return stream->line[0] == '!'; +} + +/* Retun true if the text line contains a unknown meta command. + * Otherwise the function returns false. + */ +bool Stream_lineIsUnknwnMetaCommand(Stream_t stream) +{ + size_t i = 0; + while(__metacommandlist[i]) + { + if(!strncmp(__metacommandlist[i],stream->line + 2,strlen(__metacommandlist[i]))) + return false; + i++; + } + + Stream_printLine(stream,unknwn_meta_command_line_type); + + setErrno(E_UNKWN_META_COMMAND); + return true; +} + +/* + * Return true if the text line contains a invalid + * meta command. Otherwise the function returns false. + */ +bool Stream_lineIsInvalidMetaCommand(Stream_t stream) +{ + if(!strncmp("set timeout ",stream->line + 2,strlen("set timeout "))) + { + return Stream_isInvalidTimeout(stream); + } + else if(!strncmp("command line ",stream->line + 2,strlen("command line "))) + { + Stream_printLine(stream,command_line_line_type); + } + else if(!strncmp("enable output checking",stream->line + 2,strlen("enable output checking"))) + { + Stream_printLine(stream,enable_output_checking_line_type); + } + else if(!strncmp("disable output checking",stream->line + 2,strlen("disable output checking"))) + { + Stream_printLine(stream,disable_output_checking_line_type); + } + else if(!strncmp("enable post output checking",stream->line + 2,strlen("enable post output checking"))) + { + Stream_printLine(stream,enable_post_output_checking_line_type); + } + else if(!strncmp("disable post output checking",stream->line + 2,strlen("disable post output checking"))) + { + Stream_printLine(stream,disable_post_output_checking_line_type); + } + else if(!strncmp("expect exit code ",stream->line + 2,strlen("expect exit code "))) + { + return Stream_isInvalidExpectedCode(stream); + } + else if(!strncmp("export ",stream->line + 2,strlen("export "))) + { + return Stream_isInvalidExport(stream); + } + else if(!strncmp("unset ",stream->line + 2,strlen("unset "))) + { + return Stream_isInvalidUnset(stream); + } + else if(!strncmp("create console",stream->line + 2,strlen("create console"))) + { + Stream_printLine(stream,create_console_line_type); + } + else if(!strncmp("create no console",stream->line + 2,strlen("create no console"))) + { + Stream_printLine(stream,create_no_console_line_type); + } + else if(!strncmp("enable exit code checking",stream->line + 2,strlen("enable exit code checking"))) + { + Stream_printLine(stream,enable_exit_code_checking_line_type); + } + else if(!strncmp("disable exit code checking",stream->line + 2,strlen("disaable exit code checking"))) + { + Stream_printLine(stream,disable_exit_code_checking_line_type); + } + else + { + return true; + } + + return false; + +} + + + +/* + * Print the file line. + */ +void Stream_printLine(Stream_t stream,line_type_t line_type) +{ + char* __date = NULL; + __date = (char*)calloc(1,30); + + __time(__date); + + + Stream_lock(stream); + + switch(line_type) + { + #ifdef __VERBOSE + case comment_line_type: + + if(*(stream->line+2) != '\0') + printf("%s %3d %s",__date,stream->line_number,stream->line + 2); + else + /* empty comment */ + printf("%s %3d %s",__date,stream->line_number," \n"); + break; + + case timeout_value_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line + 2 + strlen("set timeout ")); + break; + + case exit_code_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line + 2 + strlen("expect exit code ")); + break; + + case export_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line + 2); + break; + + case unset_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line + 2); + break; + + case enable_output_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case disable_output_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case enable_post_output_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case disable_post_output_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case create_console_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case create_no_console_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case enable_exit_code_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case disable_exit_code_checking_line_type: + printf("%s %3d\n",__date,stream->line_number); + break; + + case change_directory_line_type: + printf("%s %3d %s\n",__date,stream->line_number,stream->line + 5); + break; + + case command_line_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line + 2); + break; + + #endif /* #ifdef __VERBOSE */ + + case invalid_token_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case unknwn_meta_command_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case invalid_timeout_value_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case invalid_exit_code_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case invalid_export_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case invalid_unset_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case export_failed_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + case unset_failed_line_type: + printf("%s %3d %s",__date,stream->line_number,stream->line); + break; + + /* default: + ASSERT(false); + */ + } + + if(__date) + free(__date); + + Stream_unlock(stream); +} + + +/* + * Returns true if the timeout value is invalid. + * Otherwise the function returns false. + */ +bool Stream_isInvalidTimeout(Stream_t stream) +{ +size_t i = 0; + char* p = stream->line + 2 + strlen("set timeout "); + + while(p[i] != '\n') + { + if(!isdigit(p[i])) + { + setErrno(E_INVALID_TIMEOUT_VALUE); + Stream_printLine(stream,invalid_timeout_value_line_type); + return true; + } + + i++; + } + + Stream_printLine(stream,timeout_value_line_type); + return false; +} + + +/* + * Returns true if the expected code value is invalid. + * Otherwise the function returns false. + */ +bool Stream_isInvalidExpectedCode(Stream_t stream) +{ + size_t i = 0; + char* p = stream->line + 2 + strlen("expect exit code "); + + while(p[i] != '\n') + { + if(!isdigit(p[i])) + { + setErrno(E_INVALID_EXIT_CODE_VALUE); + Stream_printLine(stream,invalid_exit_code_line_type); + return true; + } + i++; + } + + Stream_printLine(stream,exit_code_line_type); + return false; +} + + +/* + * Returns true if the export is invalid. + * Otherwise the function returns false. + */ +bool Stream_isInvalidExport(Stream_t stream) +{ + /* todo trim*/ + const char* ptr = strchr(stream->line,'='); + + if(ptr && (*(++ptr) != '\n')) + { + Stream_printLine(stream,export_line_type); + return false; + } + + setErrno(E_INVALID_EXPORT); + Stream_printLine(stream,invalid_export_line_type); + return true; +} + +/* + * Returns true if the unset is invalid. + * Otherwise the function returns false. + */ +bool Stream_isInvalidUnset(Stream_t stream) +{ + /* todo trim */ + const char* ptr = strchr(stream->line,' '); + + if((*(++ptr) != '\n')) + { + Stream_printLine(stream,unset_line_type); + return false; + } + + setErrno(E_INVALID_UNSET); + Stream_printLine(stream,invalid_unset_line_type); + + + return true; +} + + +/* + * Return true if the stream line contains a + * expected child output. Otherwhise the function + * returns false. + */ + +bool Stream_lineIsExpectedChildOutput(Stream_t stream) +{ + return stream->line[0] == '>'; +} + +/* + * Return true if the stream line contains a + * child input. Otherwhise the function + * returns false. + */ +bool Stream_lineIsChildInput(Stream_t stream) +{ + return stream->line[0] == '<'; +} + + + +/* + * Return true, if the stream line containts a + * synchrone test case. otherwise the function + * returns false. + */ +bool Stream_lineIsSyncTestCase(Stream_t stream) +{ + return stream->line[0] == '$'; +} + +bool Stream_lineIsAsyncTestCase(Stream_t stream) +{ + return stream->line[0] == '&'; +} + +bool Stream_lineIsChangeDir(Stream_t stream) +{ + return ((stream->line[0] == '$') && (!strncmp(stream->line+2,"cd ",strlen("cd ")))); +} + +void Stream_lock(Stream_t ptr) +{ + EnterCriticalSection(&cs); +} + +void Stream_unlock(Stream_t ptr) +{ + LeaveCriticalSection(&cs); +} -- 2.20.1