Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
merge conflicts
[simgrid.git] / win32_test_app / src / TStream.c
1 #include <TStream.h>
2
3 extern const char *TOKENS = "$<>#!p&";
4
5 CRITICAL_SECTION cs;
6
7 const char *__metacommandlist[] = {
8   "set timeout ",
9   "enable output checking",
10   "disable output checking",
11   "enable post output checking",
12   "disable post output checking",
13   "expect exit code ",
14   "export ",
15   "unset ",
16   "create console",
17   "create no console",
18   "enable exit code checking",
19   "disable exit code checking",
20   "command line ",
21   NULL
22 };
23
24 /*
25  * Create a new s_Stream struct and return
26  * a pointer to self
27  */
28
29 Stream_t Stream_new(void)
30 {
31   Stream_t ptr = (Stream_t) calloc(1, sizeof(s_Stream_t));
32
33   if (NULL == ptr) {
34     setErrno(E_STREAM_ALLOCATION_FAILED);
35     Stream_free(ptr);
36   }
37
38   memset(&cs, 0, sizeof(CRITICAL_SECTION));
39   InitializeCriticalSection(&cs);
40
41   ptr->line = NULL;
42   ptr->line_number = 0;
43
44   return ptr;
45 }
46
47 /*
48  * Returns true if the current text line is blank.
49  */
50 bool Stream_lineIsBlank(Stream_t stream)
51 {
52   size_t i = 0;
53   char *p = (char *) stream->line;
54
55   while (p[i] != '\n') {
56     if (!Stream_isBlankChar(p[i]))
57       return false;
58     i++;
59
60   }
61
62   return true;
63 }
64
65 /* 
66  * Return true if the caracter is space or tab.
67  */
68 bool Stream_isBlankChar(char ch)
69 {
70   return ((ch == ' ') || ch == ('\t'));
71 }
72
73 /*
74  * Return E_SUCCESS if the file is valid. 
75  * Otherwise the fuction returns E_INVALID_FILE.
76  */
77 errno_t Stream_isValidFile(const char *file_name)
78 {
79   WIN32_FIND_DATA wfd = { 0 };
80   HANDLE hFile = FindFirstFile(file_name, &wfd);
81
82   if (INVALID_HANDLE_VALUE == hFile)
83     return E_FILE_NOT_FOUND;
84
85   FindClose(hFile);
86   return E_SUCCESS;
87 }
88
89 /* 
90  * Return E_SUCCESS is the open file operation succeeded.
91  * Otherwise the functions returns E_OPEN_FILE_FAILED.
92  */
93 errno_t Stream_openFile(Stream_t ptr, const char *file_name)
94 {
95   ptr->file = fopen(file_name, "r");
96
97   if (NULL == ptr->file) {
98     setErrno(E_OPEN_FILE_FAILED);
99     return getErrno();
100   }
101
102   return E_SUCCESS;
103 }
104
105 /*
106  * This function reads an entire line, storing 
107  * the address of the buffer containing the  text into  
108  * *dest. 
109  */
110 ssize_t Stream_getLine(Stream_t stream)
111 {
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;
118
119   if (NULL == file) {
120     setErrno(E_INVALID_FILE_Stream);
121     return -1;
122   }
123
124   if (NULL == stream->line) {
125     len = DEFAULT_ALLOC_SIZE;
126     stream->line = (char *) calloc(1, len);
127
128     if (NULL == stream->line) {
129       setErrno(E_STREAM_LINE_ALLOCATION_FAILED);
130       return -1;
131     }
132   } else {
133     memset(stream->line, 0, len);
134   }
135
136   capacity_available = len;
137   pos = stream->line;
138
139   while (true) {
140     ch = getc(file);
141
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)
145         len = len << 1;
146       else
147         len += DEFAULT_ALLOC_SIZE;
148
149       capacity_available = stream->line + len - pos;
150       stream->line = realloc(stream->line, len);
151
152       if (NULL == stream->line) {
153         setErrno(E_STREAM_LINE_REALLOCATION_FAILED);
154         return -1;
155       }
156
157       pos = stream->line + len - capacity_available;
158     }
159
160     if (ferror(file)) {
161       /* file error exit on error */
162       setErrno(E_STREAM_ERROR);
163       return -1;
164     }
165
166     if ((EOF == ch)) {
167       /* Empty file */
168       if (!strlen(stream->line) && !stream->line_number) {
169         setErrno(E_STREAM_EMPTY);
170         return -1;
171       }
172       /* end of file */
173       else if (!strlen(stream->line) && stream->line_number) {
174         return -1;
175       }
176
177       break;
178     }
179
180     *pos++ = ch;
181     capacity_available--;
182
183     /* we have a line, exit loop */
184     if (ch == '\n')
185       break;
186   }
187
188   /* append the zero terminal */
189
190   *pos = '\0';
191   size = pos - stream->line;
192
193   stream->line_number++;
194
195   /* size of texte line without zero terminal */
196   return size;
197 }
198
199
200 /* 
201  * Free a s_Stream.
202  */
203
204 void Stream_free(Stream_t ptr)
205 {
206   if (NULL == ptr)
207     return;
208
209   if ((NULL != ptr->file) && (stdin != ptr->file))
210     fclose(ptr->file);
211
212   free(ptr->line);
213
214   DeleteCriticalSection(&cs);
215
216   free(ptr);
217 }
218
219 /*
220  * Return true if the current line is a comment.
221  * Otherwise the functions returns false.
222  */
223 bool Stream_lineIsComment(Stream_t stream)
224 {
225   return stream->line[0] == '#';
226 }
227
228 /* Return true if the current line contains a invalide token.
229  * Otherwise, the function returns false.
230  */
231 bool Stream_lineContainsInvalidToken(Stream_t stream)
232 {
233   if (strchr(TOKENS, stream->line[0]) == NULL) {
234     Stream_printLine(stream, invalid_token_line_type);
235     setErrno(E_INVALID_TOKEN);
236     return true;
237   }
238
239   return false;
240 }
241
242 /*
243  * Return true if the text line is a meta command.
244  * Otherwise, the functions returns false.
245  */
246 bool Stream_lineIsMetacommand(Stream_t stream)
247 {
248   return stream->line[0] == '!';
249 }
250
251 /* Retun true if the text line contains a unknown meta command.
252  * Otherwise the function returns false.
253  */
254 bool Stream_lineIsUnknwnMetaCommand(Stream_t stream)
255 {
256   size_t i = 0;
257   while (__metacommandlist[i]) {
258     if (!strncmp
259         (__metacommandlist[i], stream->line + 2,
260          strlen(__metacommandlist[i])))
261       return false;
262     i++;
263   }
264
265   Stream_printLine(stream, unknwn_meta_command_line_type);
266
267   setErrno(E_UNKWN_META_COMMAND);
268   return true;
269 }
270
271 /*
272  * Return true if the text line contains a invalid 
273  * meta command. Otherwise the function returns false.
274  */
275 bool Stream_lineIsInvalidMetaCommand(Stream_t stream)
276 {
277   if (!strncmp("set timeout ", stream->line + 2, strlen("set timeout "))) {
278     return Stream_isInvalidTimeout(stream);
279   } else
280       if (!strncmp
281           ("command line ", stream->line + 2, strlen("command line "))) {
282     Stream_printLine(stream, command_line_line_type);
283   } else
284       if (!strncmp
285           ("enable output checking", stream->line + 2,
286            strlen("enable output checking"))) {
287     Stream_printLine(stream, enable_output_checking_line_type);
288   } else
289       if (!strncmp
290           ("disable output checking", stream->line + 2,
291            strlen("disable output checking"))) {
292     Stream_printLine(stream, disable_output_checking_line_type);
293   } else
294       if (!strncmp
295           ("enable post output checking", stream->line + 2,
296            strlen("enable post output checking"))) {
297     Stream_printLine(stream, enable_post_output_checking_line_type);
298   } else
299       if (!strncmp
300           ("disable post output checking", stream->line + 2,
301            strlen("disable post output checking"))) {
302     Stream_printLine(stream, disable_post_output_checking_line_type);
303   } else
304       if (!strncmp
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);
312   } else
313       if (!strncmp
314           ("create console", stream->line + 2, strlen("create console"))) {
315     Stream_printLine(stream, create_console_line_type);
316   } else
317       if (!strncmp
318           ("create no console", stream->line + 2,
319            strlen("create no console"))) {
320     Stream_printLine(stream, create_no_console_line_type);
321   } else
322       if (!strncmp
323           ("enable exit code checking", stream->line + 2,
324            strlen("enable exit code checking"))) {
325     Stream_printLine(stream, enable_exit_code_checking_line_type);
326   } else
327       if (!strncmp
328           ("disable exit code checking", stream->line + 2,
329            strlen("disaable exit code checking"))) {
330     Stream_printLine(stream, disable_exit_code_checking_line_type);
331   } else {
332     return true;
333   }
334
335   return false;
336
337 }
338
339
340
341 /*
342  * Print the file line.
343  */
344 void Stream_printLine(Stream_t stream, line_type_t line_type)
345 {
346   char *__date = NULL;
347   __date = (char *) calloc(1, 30);
348
349   __time(__date);
350
351
352   Stream_lock(stream);
353
354   switch (line_type) {
355 #ifdef __VERBOSE
356   case comment_line_type:
357
358     if (*(stream->line + 2) != '\0')
359       printf("%s   <COMMENT                     >  %3d %s", __date,
360              stream->line_number, stream->line + 2);
361     else
362       /* empty comment */
363       printf("%s   <COMMENT                     >  %3d %s", __date,
364              stream->line_number, " \n");
365     break;
366
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 "));
370     break;
371
372   case exit_code_line_type:
373     printf("%s   <EXPECTED EXIT CODE          >  %3d %s", __date,
374            stream->line_number,
375            stream->line + 2 + strlen("expect exit code "));
376     break;
377
378   case export_line_type:
379     printf("%s   <EXPORT                      >  %3d %s", __date,
380            stream->line_number, stream->line + 2);
381     break;
382
383   case unset_line_type:
384     printf("%s   <UNSET                       >  %3d %s", __date,
385            stream->line_number, stream->line + 2);
386     break;
387
388   case enable_output_checking_line_type:
389     printf("%s   <OUTPUT CHECKING ENABLED     >  %3d\n", __date,
390            stream->line_number);
391     break;
392
393   case disable_output_checking_line_type:
394     printf("%s   <OUTPUT CHECKING DISABLED    >  %3d\n", __date,
395            stream->line_number);
396     break;
397
398   case enable_post_output_checking_line_type:
399     printf("%s   <POST OUTPUT CHECKING ENABLED>  %3d\n", __date,
400            stream->line_number);
401     break;
402
403   case disable_post_output_checking_line_type:
404     printf("%s   <POST OUTPUT CHECKING DISABLED>  %3d\n", __date,
405            stream->line_number);
406     break;
407
408   case create_console_line_type:
409     printf("%s   <CREATE CONSOLE SELECTED     >  %3d\n", __date,
410            stream->line_number);
411     break;
412
413   case create_no_console_line_type:
414     printf("%s   <CREATE NO CONSOLE SELECTED  >  %3d\n", __date,
415            stream->line_number);
416     break;
417
418   case enable_exit_code_checking_line_type:
419     printf("%s   <EXIT CODE CHECKING ENABLED  >  %3d\n", __date,
420            stream->line_number);
421     break;
422
423   case disable_exit_code_checking_line_type:
424     printf("%s   <EXIT CODE CHECKING DISABLED >  %3d\n", __date,
425            stream->line_number);
426     break;
427
428   case change_directory_line_type:
429     printf("%s   <DIRECTORY IS NOW            >  %3d %s\n", __date,
430            stream->line_number, stream->line + 5);
431     break;
432
433   case command_line_line_type:
434     printf("%s   <COMMAND LINE                >  %3d %s", __date,
435            stream->line_number, stream->line + 2);
436     break;
437
438 #endif                          /* #ifdef __VERBOSE */
439
440   case invalid_token_line_type:
441     printf("%s   <INVALIDE TOKEN              >  %3d %s", __date,
442            stream->line_number, stream->line);
443     break;
444
445   case unknwn_meta_command_line_type:
446     printf("%s   <UNKNOWN META COMMAND        >  %3d %s", __date,
447            stream->line_number, stream->line);
448     break;
449
450   case invalid_timeout_value_line_type:
451     printf("%s   <INVALID TIMEOUT VALUE       >  %3d %s", __date,
452            stream->line_number, stream->line);
453     break;
454
455   case invalid_exit_code_line_type:
456     printf("%s   <INVALID EXIT CODE           >  %3d %s", __date,
457            stream->line_number, stream->line);
458     break;
459
460   case invalid_export_line_type:
461     printf("%s   <INVALID EXPORT              >  %3d %s", __date,
462            stream->line_number, stream->line);
463     break;
464
465   case invalid_unset_line_type:
466     printf("%s   <INVALID UNSET               >  %3d %s", __date,
467            stream->line_number, stream->line);
468     break;
469
470   case export_failed_line_type:
471     printf("%s   <EXPORT FAILED               >  %3d %s", __date,
472            stream->line_number, stream->line);
473     break;
474
475   case unset_failed_line_type:
476     printf("%s   <UNSET FAILED                >  %3d %s", __date,
477            stream->line_number, stream->line);
478     break;
479
480     /* default:
481        ASSERT(false);
482      */
483   }
484
485   free(__date);
486
487   Stream_unlock(stream);
488 }
489
490
491 /*
492  * Returns true if the timeout value is invalid.
493  * Otherwise the function returns false.
494  */
495 bool Stream_isInvalidTimeout(Stream_t stream)
496 {
497   size_t i = 0;
498   char *p = stream->line + 2 + strlen("set timeout ");
499
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);
504       return true;
505     }
506
507     i++;
508   }
509
510   Stream_printLine(stream, timeout_value_line_type);
511   return false;
512 }
513
514
515 /*
516  * Returns true if the expected code value is invalid.
517  * Otherwise the function returns false.
518  */
519 bool Stream_isInvalidExpectedCode(Stream_t stream)
520 {
521   size_t i = 0;
522   char *p = stream->line + 2 + strlen("expect exit code ");
523
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);
528       return true;
529     }
530     i++;
531   }
532
533   Stream_printLine(stream, exit_code_line_type);
534   return false;
535 }
536
537
538 /*
539  * Returns true if the export is invalid.
540  * Otherwise the function returns false.
541  */
542 bool Stream_isInvalidExport(Stream_t stream)
543 {
544   /* todo trim */
545   const char *ptr = strchr(stream->line, '=');
546
547   if (ptr && (*(++ptr) != '\n')) {
548     Stream_printLine(stream, export_line_type);
549     return false;
550   }
551
552   setErrno(E_INVALID_EXPORT);
553   Stream_printLine(stream, invalid_export_line_type);
554   return true;
555 }
556
557 /*
558  * Returns true if the unset is invalid.
559  * Otherwise the function returns false.
560  */
561 bool Stream_isInvalidUnset(Stream_t stream)
562 {
563   /* todo trim */
564   const char *ptr = strchr(stream->line, ' ');
565
566   if ((*(++ptr) != '\n')) {
567     Stream_printLine(stream, unset_line_type);
568     return false;
569   }
570
571   setErrno(E_INVALID_UNSET);
572   Stream_printLine(stream, invalid_unset_line_type);
573
574
575   return true;
576 }
577
578
579 /* 
580  * Return true if the stream line contains a 
581  * expected child output. Otherwhise the function
582  * returns false.
583  */
584
585 bool Stream_lineIsExpectedChildOutput(Stream_t stream)
586 {
587   return stream->line[0] == '>';
588 }
589
590 /* 
591  * Return true if the stream line contains a 
592  * child input. Otherwhise the function
593  * returns false.
594  */
595 bool Stream_lineIsChildInput(Stream_t stream)
596 {
597   return stream->line[0] == '<';
598 }
599
600
601
602 /*
603  * Return true, if the stream line containts a
604  * synchrone test case. otherwise the function
605  * returns false.
606  */
607 bool Stream_lineIsSyncTestCase(Stream_t stream)
608 {
609   return stream->line[0] == '$';
610 }
611
612 bool Stream_lineIsAsyncTestCase(Stream_t stream)
613 {
614   return stream->line[0] == '&';
615 }
616
617 bool Stream_lineIsChangeDir(Stream_t stream)
618 {
619   return ((stream->line[0] == '$')
620           && (!strncmp(stream->line + 2, "cd ", strlen("cd "))));
621 }
622
623 void Stream_lock(Stream_t ptr)
624 {
625   EnterCriticalSection(&cs);
626 }
627
628 void Stream_unlock(Stream_t ptr)
629 {
630   LeaveCriticalSection(&cs);
631 }