3 extern const char *TOKENS = "$<>#!p&";
7 const char *__metacommandlist[] = {
9 "enable output checking",
10 "disable output checking",
11 "enable post output checking",
12 "disable post output checking",
18 "enable exit code checking",
19 "disable exit code checking",
25 * Create a new s_Stream struct and return
29 Stream_t Stream_new(void)
31 Stream_t ptr = (Stream_t) calloc(1, sizeof(s_Stream_t));
34 setErrno(E_STREAM_ALLOCATION_FAILED);
38 memset(&cs, 0, sizeof(CRITICAL_SECTION));
39 InitializeCriticalSection(&cs);
48 * Returns true if the current text line is blank.
50 bool Stream_lineIsBlank(Stream_t stream)
53 char *p = (char *) stream->line;
55 while (p[i] != '\n') {
56 if (!Stream_isBlankChar(p[i]))
66 * Return true if the caracter is space or tab.
68 bool Stream_isBlankChar(char ch)
70 return ((ch == ' ') || ch == ('\t'));
74 * Return E_SUCCESS if the file is valid.
75 * Otherwise the fuction returns E_INVALID_FILE.
77 errno_t Stream_isValidFile(const char *file_name)
79 WIN32_FIND_DATA wfd = { 0 };
80 HANDLE hFile = FindFirstFile(file_name, &wfd);
82 if (INVALID_HANDLE_VALUE == hFile)
83 return E_FILE_NOT_FOUND;
90 * Return E_SUCCESS is the open file operation succeeded.
91 * Otherwise the functions returns E_OPEN_FILE_FAILED.
93 errno_t Stream_openFile(Stream_t ptr, const char *file_name)
95 ptr->file = fopen(file_name, "r");
97 if (NULL == ptr->file) {
98 setErrno(E_OPEN_FILE_FAILED);
106 * This function reads an entire line, storing
107 * the address of the buffer containing the text into
110 ssize_t Stream_getLine(Stream_t stream)
112 size_t capacity_available; /* capacity available in the buffer */
113 char *pos; /* read operation position */
114 ssize_t size; /* the size of the text line (minus the 0 terminal */
115 static size_t len = 0;
116 register int ch; /* the current character */
117 FILE *file = stream->file;
120 setErrno(E_INVALID_FILE_Stream);
124 if (NULL == stream->line) {
125 len = DEFAULT_ALLOC_SIZE;
126 stream->line = (char *) calloc(1, len);
128 if (NULL == stream->line) {
129 setErrno(E_STREAM_LINE_ALLOCATION_FAILED);
133 memset(stream->line, 0, len);
136 capacity_available = len;
142 /* un byte for the next char and one byte for the zero terminal. */
143 if (capacity_available < 2) {
144 if (len > DEFAULT_ALLOC_SIZE)
147 len += DEFAULT_ALLOC_SIZE;
149 capacity_available = stream->line + len - pos;
150 stream->line = realloc(stream->line, len);
152 if (NULL == stream->line) {
153 setErrno(E_STREAM_LINE_REALLOCATION_FAILED);
157 pos = stream->line + len - capacity_available;
161 /* file error exit on error */
162 setErrno(E_STREAM_ERROR);
168 if (!strlen(stream->line) && !stream->line_number) {
169 setErrno(E_STREAM_EMPTY);
173 else if (!strlen(stream->line) && stream->line_number) {
181 capacity_available--;
183 /* we have a line, exit loop */
188 /* append the zero terminal */
191 size = pos - stream->line;
193 stream->line_number++;
195 /* size of texte line without zero terminal */
204 void Stream_free(Stream_t ptr)
209 if ((NULL != ptr->file) && (stdin != ptr->file))
214 DeleteCriticalSection(&cs);
220 * Return true if the current line is a comment.
221 * Otherwise the functions returns false.
223 bool Stream_lineIsComment(Stream_t stream)
225 return stream->line[0] == '#';
228 /* Return true if the current line contains a invalide token.
229 * Otherwise, the function returns false.
231 bool Stream_lineContainsInvalidToken(Stream_t stream)
233 if (strchr(TOKENS, stream->line[0]) == NULL) {
234 Stream_printLine(stream, invalid_token_line_type);
235 setErrno(E_INVALID_TOKEN);
243 * Return true if the text line is a meta command.
244 * Otherwise, the functions returns false.
246 bool Stream_lineIsMetacommand(Stream_t stream)
248 return stream->line[0] == '!';
251 /* Retun true if the text line contains a unknown meta command.
252 * Otherwise the function returns false.
254 bool Stream_lineIsUnknwnMetaCommand(Stream_t stream)
257 while (__metacommandlist[i]) {
259 (__metacommandlist[i], stream->line + 2,
260 strlen(__metacommandlist[i])))
265 Stream_printLine(stream, unknwn_meta_command_line_type);
267 setErrno(E_UNKWN_META_COMMAND);
272 * Return true if the text line contains a invalid
273 * meta command. Otherwise the function returns false.
275 bool Stream_lineIsInvalidMetaCommand(Stream_t stream)
277 if (!strncmp("set timeout ", stream->line + 2, strlen("set timeout "))) {
278 return Stream_isInvalidTimeout(stream);
281 ("command line ", stream->line + 2, strlen("command line "))) {
282 Stream_printLine(stream, command_line_line_type);
285 ("enable output checking", stream->line + 2,
286 strlen("enable output checking"))) {
287 Stream_printLine(stream, enable_output_checking_line_type);
290 ("disable output checking", stream->line + 2,
291 strlen("disable output checking"))) {
292 Stream_printLine(stream, disable_output_checking_line_type);
295 ("enable post output checking", stream->line + 2,
296 strlen("enable post output checking"))) {
297 Stream_printLine(stream, enable_post_output_checking_line_type);
300 ("disable post output checking", stream->line + 2,
301 strlen("disable post output checking"))) {
302 Stream_printLine(stream, disable_post_output_checking_line_type);
305 ("expect exit code ", stream->line + 2,
306 strlen("expect exit code "))) {
307 return Stream_isInvalidExpectedCode(stream);
308 } else if (!strncmp("export ", stream->line + 2, strlen("export "))) {
309 return Stream_isInvalidExport(stream);
310 } else if (!strncmp("unset ", stream->line + 2, strlen("unset "))) {
311 return Stream_isInvalidUnset(stream);
314 ("create console", stream->line + 2, strlen("create console"))) {
315 Stream_printLine(stream, create_console_line_type);
318 ("create no console", stream->line + 2,
319 strlen("create no console"))) {
320 Stream_printLine(stream, create_no_console_line_type);
323 ("enable exit code checking", stream->line + 2,
324 strlen("enable exit code checking"))) {
325 Stream_printLine(stream, enable_exit_code_checking_line_type);
328 ("disable exit code checking", stream->line + 2,
329 strlen("disaable exit code checking"))) {
330 Stream_printLine(stream, disable_exit_code_checking_line_type);
342 * Print the file line.
344 void Stream_printLine(Stream_t stream, line_type_t line_type)
347 __date = (char *) calloc(1, 30);
356 case comment_line_type:
358 if (*(stream->line + 2) != '\0')
359 printf("%s <COMMENT > %3d %s", __date,
360 stream->line_number, stream->line + 2);
363 printf("%s <COMMENT > %3d %s", __date,
364 stream->line_number, " \n");
367 case timeout_value_line_type:
368 printf("%s <TIMEOUT VALUE IS NOW > %3d %s", __date,
369 stream->line_number, stream->line + 2 + strlen("set timeout "));
372 case exit_code_line_type:
373 printf("%s <EXPECTED EXIT CODE > %3d %s", __date,
375 stream->line + 2 + strlen("expect exit code "));
378 case export_line_type:
379 printf("%s <EXPORT > %3d %s", __date,
380 stream->line_number, stream->line + 2);
383 case unset_line_type:
384 printf("%s <UNSET > %3d %s", __date,
385 stream->line_number, stream->line + 2);
388 case enable_output_checking_line_type:
389 printf("%s <OUTPUT CHECKING ENABLED > %3d\n", __date,
390 stream->line_number);
393 case disable_output_checking_line_type:
394 printf("%s <OUTPUT CHECKING DISABLED > %3d\n", __date,
395 stream->line_number);
398 case enable_post_output_checking_line_type:
399 printf("%s <POST OUTPUT CHECKING ENABLED> %3d\n", __date,
400 stream->line_number);
403 case disable_post_output_checking_line_type:
404 printf("%s <POST OUTPUT CHECKING DISABLED> %3d\n", __date,
405 stream->line_number);
408 case create_console_line_type:
409 printf("%s <CREATE CONSOLE SELECTED > %3d\n", __date,
410 stream->line_number);
413 case create_no_console_line_type:
414 printf("%s <CREATE NO CONSOLE SELECTED > %3d\n", __date,
415 stream->line_number);
418 case enable_exit_code_checking_line_type:
419 printf("%s <EXIT CODE CHECKING ENABLED > %3d\n", __date,
420 stream->line_number);
423 case disable_exit_code_checking_line_type:
424 printf("%s <EXIT CODE CHECKING DISABLED > %3d\n", __date,
425 stream->line_number);
428 case change_directory_line_type:
429 printf("%s <DIRECTORY IS NOW > %3d %s\n", __date,
430 stream->line_number, stream->line + 5);
433 case command_line_line_type:
434 printf("%s <COMMAND LINE > %3d %s", __date,
435 stream->line_number, stream->line + 2);
438 #endif /* #ifdef __VERBOSE */
440 case invalid_token_line_type:
441 printf("%s <INVALIDE TOKEN > %3d %s", __date,
442 stream->line_number, stream->line);
445 case unknwn_meta_command_line_type:
446 printf("%s <UNKNOWN META COMMAND > %3d %s", __date,
447 stream->line_number, stream->line);
450 case invalid_timeout_value_line_type:
451 printf("%s <INVALID TIMEOUT VALUE > %3d %s", __date,
452 stream->line_number, stream->line);
455 case invalid_exit_code_line_type:
456 printf("%s <INVALID EXIT CODE > %3d %s", __date,
457 stream->line_number, stream->line);
460 case invalid_export_line_type:
461 printf("%s <INVALID EXPORT > %3d %s", __date,
462 stream->line_number, stream->line);
465 case invalid_unset_line_type:
466 printf("%s <INVALID UNSET > %3d %s", __date,
467 stream->line_number, stream->line);
470 case export_failed_line_type:
471 printf("%s <EXPORT FAILED > %3d %s", __date,
472 stream->line_number, stream->line);
475 case unset_failed_line_type:
476 printf("%s <UNSET FAILED > %3d %s", __date,
477 stream->line_number, stream->line);
487 Stream_unlock(stream);
492 * Returns true if the timeout value is invalid.
493 * Otherwise the function returns false.
495 bool Stream_isInvalidTimeout(Stream_t stream)
498 char *p = stream->line + 2 + strlen("set timeout ");
500 while (p[i] != '\n') {
501 if (!isdigit(p[i])) {
502 setErrno(E_INVALID_TIMEOUT_VALUE);
503 Stream_printLine(stream, invalid_timeout_value_line_type);
510 Stream_printLine(stream, timeout_value_line_type);
516 * Returns true if the expected code value is invalid.
517 * Otherwise the function returns false.
519 bool Stream_isInvalidExpectedCode(Stream_t stream)
522 char *p = stream->line + 2 + strlen("expect exit code ");
524 while (p[i] != '\n') {
525 if (!isdigit(p[i])) {
526 setErrno(E_INVALID_EXIT_CODE_VALUE);
527 Stream_printLine(stream, invalid_exit_code_line_type);
533 Stream_printLine(stream, exit_code_line_type);
539 * Returns true if the export is invalid.
540 * Otherwise the function returns false.
542 bool Stream_isInvalidExport(Stream_t stream)
545 const char *ptr = strchr(stream->line, '=');
547 if (ptr && (*(++ptr) != '\n')) {
548 Stream_printLine(stream, export_line_type);
552 setErrno(E_INVALID_EXPORT);
553 Stream_printLine(stream, invalid_export_line_type);
558 * Returns true if the unset is invalid.
559 * Otherwise the function returns false.
561 bool Stream_isInvalidUnset(Stream_t stream)
564 const char *ptr = strchr(stream->line, ' ');
566 if ((*(++ptr) != '\n')) {
567 Stream_printLine(stream, unset_line_type);
571 setErrno(E_INVALID_UNSET);
572 Stream_printLine(stream, invalid_unset_line_type);
580 * Return true if the stream line contains a
581 * expected child output. Otherwhise the function
585 bool Stream_lineIsExpectedChildOutput(Stream_t stream)
587 return stream->line[0] == '>';
591 * Return true if the stream line contains a
592 * child input. Otherwhise the function
595 bool Stream_lineIsChildInput(Stream_t stream)
597 return stream->line[0] == '<';
603 * Return true, if the stream line containts a
604 * synchrone test case. otherwise the function
607 bool Stream_lineIsSyncTestCase(Stream_t stream)
609 return stream->line[0] == '$';
612 bool Stream_lineIsAsyncTestCase(Stream_t stream)
614 return stream->line[0] == '&';
617 bool Stream_lineIsChangeDir(Stream_t stream)
619 return ((stream->line[0] == '$')
620 && (!strncmp(stream->line + 2, "cd ", strlen("cd "))));
623 void Stream_lock(Stream_t ptr)
625 EnterCriticalSection(&cs);
628 void Stream_unlock(Stream_t ptr)
630 LeaveCriticalSection(&cs);