Logo AND Algorithmique Numérique Distribuée

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