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))
212 if (NULL != ptr->line)
215 DeleteCriticalSection(&cs);
221 * Return true if the current line is a comment.
222 * Otherwise the functions returns false.
224 bool Stream_lineIsComment(Stream_t stream)
226 return stream->line[0] == '#';
229 /* Return true if the current line contains a invalide token.
230 * Otherwise, the function returns false.
232 bool Stream_lineContainsInvalidToken(Stream_t stream)
234 if (strchr(TOKENS, stream->line[0]) == NULL) {
235 Stream_printLine(stream, invalid_token_line_type);
236 setErrno(E_INVALID_TOKEN);
244 * Return true if the text line is a meta command.
245 * Otherwise, the functions returns false.
247 bool Stream_lineIsMetacommand(Stream_t stream)
249 return stream->line[0] == '!';
252 /* Retun true if the text line contains a unknown meta command.
253 * Otherwise the function returns false.
255 bool Stream_lineIsUnknwnMetaCommand(Stream_t stream)
258 while (__metacommandlist[i]) {
260 (__metacommandlist[i], stream->line + 2,
261 strlen(__metacommandlist[i])))
266 Stream_printLine(stream, unknwn_meta_command_line_type);
268 setErrno(E_UNKWN_META_COMMAND);
273 * Return true if the text line contains a invalid
274 * meta command. Otherwise the function returns false.
276 bool Stream_lineIsInvalidMetaCommand(Stream_t stream)
278 if (!strncmp("set timeout ", stream->line + 2, strlen("set timeout "))) {
279 return Stream_isInvalidTimeout(stream);
282 ("command line ", stream->line + 2, strlen("command line "))) {
283 Stream_printLine(stream, command_line_line_type);
286 ("enable output checking", stream->line + 2,
287 strlen("enable output checking"))) {
288 Stream_printLine(stream, enable_output_checking_line_type);
291 ("disable output checking", stream->line + 2,
292 strlen("disable output checking"))) {
293 Stream_printLine(stream, disable_output_checking_line_type);
296 ("enable post output checking", stream->line + 2,
297 strlen("enable post output checking"))) {
298 Stream_printLine(stream, enable_post_output_checking_line_type);
301 ("disable post output checking", stream->line + 2,
302 strlen("disable post output checking"))) {
303 Stream_printLine(stream, disable_post_output_checking_line_type);
306 ("expect exit code ", stream->line + 2,
307 strlen("expect exit code "))) {
308 return Stream_isInvalidExpectedCode(stream);
309 } else if (!strncmp("export ", stream->line + 2, strlen("export "))) {
310 return Stream_isInvalidExport(stream);
311 } else if (!strncmp("unset ", stream->line + 2, strlen("unset "))) {
312 return Stream_isInvalidUnset(stream);
315 ("create console", stream->line + 2, strlen("create console"))) {
316 Stream_printLine(stream, create_console_line_type);
319 ("create no console", stream->line + 2,
320 strlen("create no console"))) {
321 Stream_printLine(stream, create_no_console_line_type);
324 ("enable exit code checking", stream->line + 2,
325 strlen("enable exit code checking"))) {
326 Stream_printLine(stream, enable_exit_code_checking_line_type);
329 ("disable exit code checking", stream->line + 2,
330 strlen("disaable exit code checking"))) {
331 Stream_printLine(stream, disable_exit_code_checking_line_type);
343 * Print the file line.
345 void Stream_printLine(Stream_t stream, line_type_t line_type)
348 __date = (char *) calloc(1, 30);
357 case comment_line_type:
359 if (*(stream->line + 2) != '\0')
360 printf("%s <COMMENT > %3d %s", __date,
361 stream->line_number, stream->line + 2);
364 printf("%s <COMMENT > %3d %s", __date,
365 stream->line_number, " \n");
368 case timeout_value_line_type:
369 printf("%s <TIMEOUT VALUE IS NOW > %3d %s", __date,
370 stream->line_number, stream->line + 2 + strlen("set timeout "));
373 case exit_code_line_type:
374 printf("%s <EXPECTED EXIT CODE > %3d %s", __date,
376 stream->line + 2 + strlen("expect exit code "));
379 case export_line_type:
380 printf("%s <EXPORT > %3d %s", __date,
381 stream->line_number, stream->line + 2);
384 case unset_line_type:
385 printf("%s <UNSET > %3d %s", __date,
386 stream->line_number, stream->line + 2);
389 case enable_output_checking_line_type:
390 printf("%s <OUTPUT CHECKING ENABLED > %3d\n", __date,
391 stream->line_number);
394 case disable_output_checking_line_type:
395 printf("%s <OUTPUT CHECKING DISABLED > %3d\n", __date,
396 stream->line_number);
399 case enable_post_output_checking_line_type:
400 printf("%s <POST OUTPUT CHECKING ENABLED> %3d\n", __date,
401 stream->line_number);
404 case disable_post_output_checking_line_type:
405 printf("%s <POST OUTPUT CHECKING DISABLED> %3d\n", __date,
406 stream->line_number);
409 case create_console_line_type:
410 printf("%s <CREATE CONSOLE SELECTED > %3d\n", __date,
411 stream->line_number);
414 case create_no_console_line_type:
415 printf("%s <CREATE NO CONSOLE SELECTED > %3d\n", __date,
416 stream->line_number);
419 case enable_exit_code_checking_line_type:
420 printf("%s <EXIT CODE CHECKING ENABLED > %3d\n", __date,
421 stream->line_number);
424 case disable_exit_code_checking_line_type:
425 printf("%s <EXIT CODE CHECKING DISABLED > %3d\n", __date,
426 stream->line_number);
429 case change_directory_line_type:
430 printf("%s <DIRECTORY IS NOW > %3d %s\n", __date,
431 stream->line_number, stream->line + 5);
434 case command_line_line_type:
435 printf("%s <COMMAND LINE > %3d %s", __date,
436 stream->line_number, stream->line + 2);
439 #endif /* #ifdef __VERBOSE */
441 case invalid_token_line_type:
442 printf("%s <INVALIDE TOKEN > %3d %s", __date,
443 stream->line_number, stream->line);
446 case unknwn_meta_command_line_type:
447 printf("%s <UNKNOWN META COMMAND > %3d %s", __date,
448 stream->line_number, stream->line);
451 case invalid_timeout_value_line_type:
452 printf("%s <INVALID TIMEOUT VALUE > %3d %s", __date,
453 stream->line_number, stream->line);
456 case invalid_exit_code_line_type:
457 printf("%s <INVALID EXIT CODE > %3d %s", __date,
458 stream->line_number, stream->line);
461 case invalid_export_line_type:
462 printf("%s <INVALID EXPORT > %3d %s", __date,
463 stream->line_number, stream->line);
466 case invalid_unset_line_type:
467 printf("%s <INVALID UNSET > %3d %s", __date,
468 stream->line_number, stream->line);
471 case export_failed_line_type:
472 printf("%s <EXPORT FAILED > %3d %s", __date,
473 stream->line_number, stream->line);
476 case unset_failed_line_type:
477 printf("%s <UNSET FAILED > %3d %s", __date,
478 stream->line_number, stream->line);
489 Stream_unlock(stream);
494 * Returns true if the timeout value is invalid.
495 * Otherwise the function returns false.
497 bool Stream_isInvalidTimeout(Stream_t stream)
500 char *p = stream->line + 2 + strlen("set timeout ");
502 while (p[i] != '\n') {
503 if (!isdigit(p[i])) {
504 setErrno(E_INVALID_TIMEOUT_VALUE);
505 Stream_printLine(stream, invalid_timeout_value_line_type);
512 Stream_printLine(stream, timeout_value_line_type);
518 * Returns true if the expected code value is invalid.
519 * Otherwise the function returns false.
521 bool Stream_isInvalidExpectedCode(Stream_t stream)
524 char *p = stream->line + 2 + strlen("expect exit code ");
526 while (p[i] != '\n') {
527 if (!isdigit(p[i])) {
528 setErrno(E_INVALID_EXIT_CODE_VALUE);
529 Stream_printLine(stream, invalid_exit_code_line_type);
535 Stream_printLine(stream, exit_code_line_type);
541 * Returns true if the export is invalid.
542 * Otherwise the function returns false.
544 bool Stream_isInvalidExport(Stream_t stream)
547 const char *ptr = strchr(stream->line, '=');
549 if (ptr && (*(++ptr) != '\n')) {
550 Stream_printLine(stream, export_line_type);
554 setErrno(E_INVALID_EXPORT);
555 Stream_printLine(stream, invalid_export_line_type);
560 * Returns true if the unset is invalid.
561 * Otherwise the function returns false.
563 bool Stream_isInvalidUnset(Stream_t stream)
566 const char *ptr = strchr(stream->line, ' ');
568 if ((*(++ptr) != '\n')) {
569 Stream_printLine(stream, unset_line_type);
573 setErrno(E_INVALID_UNSET);
574 Stream_printLine(stream, invalid_unset_line_type);
582 * Return true if the stream line contains a
583 * expected child output. Otherwhise the function
587 bool Stream_lineIsExpectedChildOutput(Stream_t stream)
589 return stream->line[0] == '>';
593 * Return true if the stream line contains a
594 * child input. Otherwhise the function
597 bool Stream_lineIsChildInput(Stream_t stream)
599 return stream->line[0] == '<';
605 * Return true, if the stream line containts a
606 * synchrone test case. otherwise the function
609 bool Stream_lineIsSyncTestCase(Stream_t stream)
611 return stream->line[0] == '$';
614 bool Stream_lineIsAsyncTestCase(Stream_t stream)
616 return stream->line[0] == '&';
619 bool Stream_lineIsChangeDir(Stream_t stream)
621 return ((stream->line[0] == '$')
622 && (!strncmp(stream->line + 2, "cd ", strlen("cd "))));
625 void Stream_lock(Stream_t ptr)
627 EnterCriticalSection(&cs);
630 void Stream_unlock(Stream_t ptr)
632 LeaveCriticalSection(&cs);