Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
tesh version 2
[simgrid.git] / tools / tesh2 / src / fstream.c
1 #include <fstream.h>
2 #include <errno.h>
3 #include <context.h>
4 #include <command.h>
5 #include <unit.h>
6
7 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
8
9 fstream_t
10 fstream_new(const char* directory, const char* name)
11 {
12         fstream_t fstream;
13         /*struct stat buffer = {0};*/
14                 
15         if(!name)
16         {
17                 errno = EINVAL;
18                 return NULL;
19         }
20         
21         if(!directory && !strcmp("stdin", name))
22         {
23                 fstream = xbt_new0(s_fstream_t, 1);
24                 fstream->name = strdup("stdin");
25                 return fstream;
26         }
27         else if(!directory)
28         {
29                 errno = EINVAL;
30                 return NULL;
31         }
32         
33         /*if(stat(name, &buffer))
34                 return NULL;
35         
36         if(!S_ISREG(buffer.st_mode))
37         {
38                 errno = ENOENT;
39                 return NULL;
40         }*/
41         
42         fstream = xbt_new0(s_fstream_t, 1);
43         
44         fstream->name = strdup(name);
45         
46         fstream->directory = strdup(directory);
47         fstream->stream = NULL;
48         
49         
50         return fstream;
51 }
52
53 int
54 fstream_open(fstream_t fstream)
55 {
56         if(!fstream || fstream->stream)
57                 return EINVAL;
58                 
59         if(!strcmp(fstream->name, "stdin"))
60         {
61                 fstream->stream = stdin;
62                 return 0;
63         }
64         
65         if(!(fstream->stream = fopen(fstream->name, "r")))
66                 return errno;
67         
68         return 0;
69 }
70
71 int
72 fstream_close(fstream_t fstream)
73 {
74         if(!fstream || !strcmp(fstream->name, "stdin"))
75                 return EINVAL;
76                 
77         if(!fstream->stream)
78                 return EBADF;   
79         
80         fclose(fstream->stream);
81         fstream->stream = NULL;
82         return errno;
83 }
84
85 int
86 fstream_free(void** fstreamptr)
87 {
88         if(!(*fstreamptr))
89                 return EINVAL;
90                 
91         if((*((fstream_t*)fstreamptr))->stream)
92                 fclose((*((fstream_t*)fstreamptr))->stream);
93         
94         free((*((fstream_t*)fstreamptr))->name);
95         
96         if((*((fstream_t*)fstreamptr))->directory)
97                 free((*((fstream_t*)fstreamptr))->directory);
98                 
99         free(*fstreamptr);
100         
101         *fstreamptr = NULL;
102         
103         return 0;
104                 
105 }
106
107 void
108 fstream_parse( fstream_t fstream, unit_t unit)
109 {
110         size_t len;
111         char * line = NULL;
112         int line_num = 0;
113         char file_pos[256];
114         xbt_strbuff_t buff;
115         int buffbegin = 0; 
116         context_t context;
117         xbt_os_mutex_t mutex = unit->mutex;
118         
119         /* Count the line length while checking wheather it's blank */
120         int blankline;
121         int linelen;    
122         /* Deal with \ at the end of the line, and call handle_line on result */
123         int to_be_continued;
124         
125         buff=xbt_strbuff_new();
126         context = context_new();
127         
128         while(!unit->interrupted  && getline(&line, &len, fstream->stream) != -1)
129         {
130                 blankline=1;
131                 linelen = 0;    
132                 to_be_continued = 0;
133
134                 line_num++;
135                 
136                 while(line[linelen] != '\0') 
137                 {
138                         if (line[linelen] != ' ' && line[linelen] != '\t' && line[linelen]!='\n' && line[linelen]!='\r')
139                                 blankline = 0;
140                         
141                         linelen++;
142                 }
143         
144                 if(blankline) 
145                 {
146                         if(!context->command_line && (context->input->used || context->output->used))
147                         {
148                                 ERROR1("[%d] Error: no command found in this chunk of lines.",buffbegin);
149                                 
150                                 if(unit->parsing_include_file)
151                                         ERROR1("Unit `%s': NOK (syntax error)", fstream->name);
152                                 else
153                                         ERROR2("Unit `%s' inclued in `%s' : NOK (syntax error)", fstream->name, fstream->name); 
154                                 
155                                 exit_code = ESYNTAX;
156                                 unit_handle_failure(unit);
157                                 break;
158                         }
159                         
160                         if(context->command_line)
161                         {
162                                 if(!want_dry_run)
163                                 {
164                                         command_t command = command_new(unit, context, mutex);
165                                         command_run(command);
166                                 }
167                                 
168                                 context_reset(context);
169                         }
170                 
171                 
172                         continue;
173                         
174                 }
175                 
176                 if(linelen>1 && line[linelen-2]=='\\') 
177                 {
178                         if (linelen>2 && line[linelen-3] == '\\') 
179                         {
180                                 /* Damn. Escaped \ */
181                                 line[linelen-2] = '\n';
182                                 line[linelen-1] = '\0';
183                         } 
184                         else 
185                         {
186                                 to_be_continued = 1;
187                                 line[linelen-2] = '\0';
188                                 linelen -= 2;  
189                                 
190                                 if (!buff->used)
191                                         buffbegin = line_num;
192                         }
193                 }
194         
195                 if(buff->used || to_be_continued) 
196                 { 
197                         xbt_strbuff_append(buff,line);
198         
199                         if (!to_be_continued) 
200                         {
201                                 snprintf(file_pos,256,"%s:%d",fstream->name, buffbegin);
202                                 unit_handle_line(unit, context, mutex, file_pos, buff->data);    
203                                 xbt_strbuff_empty(buff);
204                         }
205                 } 
206                 else 
207                 {
208                         snprintf(file_pos,256,"%s:%d",fstream->name, line_num);
209                         unit_handle_line(unit, context, mutex, file_pos, line);      
210                 }
211         }
212         
213         /* Check that last command of the file ran well */
214         if(context->command_line)
215         {
216                 if(!want_dry_run)
217                 {
218                         command_t command = command_new(unit, context, mutex);
219                         command_run(command);
220                 }
221                 
222                 context_reset(context);
223         }
224
225         /* Clear buffers */
226         if (line)
227                 free(line);
228                 
229         xbt_strbuff_free(buff); 
230 }
231
232