bug fixed
[lttv.git] / ltt / branches / poly / ltt / facility.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4
5 #include <ltt/LTTTypes.h>
6 #include "parser.h"
7 #include <ltt/facility.h>
8
9 /* search for the (named) type in the table, if it does not exist
10 create a new one */
11 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
12
13 /* construct directed acyclic graph for types, and tree for fields */
14 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
15 LttField * fld);
16
17 /* generate the facility according to the events belongin to it */
18 void generateFacility(LttFacility * f, facility * fac,
19 LttChecksum checksum);
20
21 /* functions to release the memory occupied by a facility */
22 void freeFacility(LttFacility * facility);
23 void freeEventtype(LttEventType * evType);
24 void freeAllNamedTypes(table * named_types);
25 void freeAllUnamedTypes(sequence * unnamed_types);
26 void freeAllFields(sequence * all_fields);
27 void freeLttType(LttType * type);
28 void freeLttField(LttField * fld);
29
30
31 /*****************************************************************************
32 *Function name
33 * ltt_facility_open : open facilities
34 *Input params
35 * t : the trace containing the facilities
36 * pathname : the path name of the facility
37 ****************************************************************************/
38
39 void ltt_facility_open(LttTrace * t, char * pathname)
40 {
41 char *token;
42 parse_file in;
43 char buffer[BUFFER_SIZE];
44 facility * fac;
45 LttFacility * f;
46 LttChecksum checksum;
47
48 in.buffer = buffer;
49 in.lineno = 0;
50 in.error = error_callback;
51 in.name = pathname;
52
53 in.fp = fopen(in.name, "r");
54 if(!in.fp ) in.error(&in,"cannot open input file");
55
56 while(1){
57 token = getToken(&in);
58 if(in.type == ENDFILE) break;
59
60 if(strcmp(token, "<")) in.error(&in,"not a facility file");
61 token = getName(&in);
62
63 if(strcmp("facility",token) == 0) {
64 fac = g_new(facility, 1);
65 fac->name = NULL;
66 fac->description = NULL;
67 sequence_init(&(fac->events));
68 table_init(&(fac->named_types));
69 sequence_init(&(fac->unnamed_types));
70
71 parseFacility(&in, fac);
72
73 //check if any namedType is not defined
74 checkNamedTypesImplemented(&fac->named_types);
75
76 generateChecksum(fac->name, &checksum, &fac->events);
77
78 f = g_new(LttFacility,1);
79 generateFacility(f, fac, checksum);
80
81 t->facility_number++;
82 g_ptr_array_add(t->facilities,f);
83
84 free(fac->name);
85 free(fac->description);
86 freeEvents(&fac->events);
87 sequence_dispose(&fac->events);
88 freeNamedType(&fac->named_types);
89 table_dispose(&fac->named_types);
90 freeTypes(&fac->unnamed_types);
91 sequence_dispose(&fac->unnamed_types);
92 free(fac);
93 }
94 else in.error(&in,"facility token was expected");
95 }
96 fclose(in.fp);
97 }
98
99
100 /*****************************************************************************
101 *Function name
102 * generateFacility : generate facility, internal function
103 *Input params
104 * facility : LttFacilty structure
105 * fac : facility structure
106 * checksum : checksum of the facility
107 ****************************************************************************/
108
109 void generateFacility(LttFacility *f, facility *fac,LttChecksum checksum)
110 {
111 char * facilityName = fac->name;
112 sequence * events = &fac->events;
113 int i;
114 LttEventType * evType;
115 LttField * field;
116 LttType * type;
117
118 f->name = g_strdup(facilityName);
119 f->event_number = events->position;
120 f->checksum = checksum;
121
122 //initialize inner structures
123 f->events = g_new(LttEventType*,f->event_number);
124 sequence_init(&(f->all_fields));
125 sequence_init(&(f->all_unnamed_types));
126 table_init(&(f->all_named_types));
127
128 //for each event, construct field tree and type graph
129 for(i=0;i<events->position;i++){
130 evType = g_new(LttEventType,1);
131 f->events[i] = evType;
132
133 evType->name = g_strdup(((event*)(events->array[i]))->name);
134 evType->description=g_strdup(((event*)(events->array[i]))->description);
135
136 field = g_new(LttField, 1);
137 sequence_push(&(f->all_fields), field);
138 evType->root_field = field;
139 evType->facility = f;
140 evType->index = i;
141
142 if(((event*)(events->array[i]))->type != NULL){
143 field->field_pos = 0;
144 type = lookup_named_type(f,((event*)(events->array[i]))->type);
145 field->field_type = type;
146 field->offset_root = 0;
147 field->fixed_root = 1;
148 field->offset_parent = 0;
149 field->fixed_parent = 1;
150 // field->base_address = NULL;
151 field->field_size = 0;
152 field->field_fixed = -1;
153 field->parent = NULL;
154 field->child = NULL;
155 field->current_element = 0;
156
157 //construct field tree and type graph
158 constructTypeAndFields(f,((event*)(events->array[i]))->type,field);
159 }else{
160 evType->root_field = NULL;
161 g_free(field);
162 }
163 }
164 }
165
166
167 /*****************************************************************************
168 *Function name
169 * constructTypeAndFields : construct field tree and type graph,
170 * internal recursion function
171 *Input params
172 * fac : facility struct
173 * td : type descriptor
174 * root_field : root field of the event
175 ****************************************************************************/
176
177 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
178 LttField * fld)
179 {
180 int i;
181 type_descriptor * tmpTd;
182
183 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
184 // fld->field_size = 0;
185 // else fld->field_size = -1;
186
187 if(td->type == LTT_ENUM){
188 fld->field_type->element_number = td->labels.position;
189 fld->field_type->enum_strings = g_new(char*,td->labels.position);
190 for(i=0;i<td->labels.position;i++){
191 fld->field_type->enum_strings[i]
192 = g_strdup(((char*)(td->labels.array[i])));
193 }
194 }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
195 if(td->type == LTT_ARRAY)
196 fld->field_type->element_number = (unsigned)td->size;
197 fld->field_type->element_type = g_new(LttType*,1);
198 tmpTd = td->nested_type;
199 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
200 fld->child = g_new(LttField*, 1);
201 fld->child[0] = g_new(LttField, 1);
202 sequence_push(&(fac->all_fields), fld->child[0]);
203
204 fld->child[0]->field_pos = 0;
205 fld->child[0]->field_type = fld->field_type->element_type[0];
206 fld->child[0]->offset_root = fld->offset_root;
207 fld->child[0]->fixed_root = fld->fixed_root;
208 fld->child[0]->offset_parent = 0;
209 fld->child[0]->fixed_parent = 1;
210 // fld->child[0]->base_address = NULL;
211 fld->child[0]->field_size = 0;
212 fld->child[0]->field_fixed = -1;
213 fld->child[0]->parent = fld;
214 fld->child[0]->child = NULL;
215 fld->child[0]->current_element = 0;
216 constructTypeAndFields(fac, tmpTd, fld->child[0]);
217 }else if(td->type == LTT_STRUCT){
218 fld->field_type->element_number = td->fields.position;
219 fld->field_type->element_type = g_new(LttType*, td->fields.position);
220 fld->child = g_new(LttField*, td->fields.position);
221 for(i=0;i<td->fields.position;i++){
222 tmpTd = ((field*)(td->fields.array[i]))->type;
223 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
224 fld->child[i] = g_new(LttField,1);
225 sequence_push(&(fac->all_fields), fld->child[i]);
226
227 fld->child[i]->field_pos = i;
228 fld->child[i]->field_type = fld->field_type->element_type[i];
229 fld->child[i]->field_type->element_name
230 = g_strdup(((field*)(td->fields.array[i]))->name);
231 fld->child[i]->offset_root = -1;
232 fld->child[i]->fixed_root = -1;
233 fld->child[i]->offset_parent = -1;
234 fld->child[i]->fixed_parent = -1;
235 // fld->child[i]->base_address = NULL;
236 fld->child[i]->field_size = 0;
237 fld->child[i]->field_fixed = -1;
238 fld->child[i]->parent = fld;
239 fld->child[i]->child = NULL;
240 fld->child[i]->current_element = 0;
241 constructTypeAndFields(fac, tmpTd, fld->child[i]);
242 }
243 }
244 }
245
246
247 /*****************************************************************************
248 *Function name
249 * lookup_named_type: search named type in the table
250 * internal function
251 *Input params
252 * fac : facility struct
253 * td : type descriptor
254 *Return value
255 * : either find the named type, or create a new LttType
256 ****************************************************************************/
257
258 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
259 {
260 LttType * lttType = NULL;
261 int i;
262 char * name;
263 if(td->type_name){
264 for(i=0;i<fac->all_named_types.keys.position;i++){
265 name = (char *)(fac->all_named_types.keys.array[i]);
266 if(strcmp(name, td->type_name)==0){
267 lttType = (LttType*)(fac->all_named_types.values.array[i]);
268 break;
269 }
270 }
271 }
272
273 if(!lttType){
274 lttType = g_new(LttType,1);
275 lttType->type_class = td->type;
276 if(td->fmt) lttType->fmt = g_strdup(td->fmt);
277 else lttType->fmt = NULL;
278 lttType->size = td->size;
279 lttType->enum_strings = NULL;
280 lttType->element_type = NULL;
281 lttType->element_number = 0;
282 if(td->type_name){
283 name = g_strdup(td->type_name);
284 table_insert(&(fac->all_named_types),name,lttType);
285 lttType->element_name = name;
286 }
287 else{
288 sequence_push(&(fac->all_unnamed_types), lttType);
289 lttType->element_name = NULL;
290 }
291 }
292
293 return lttType;
294 }
295
296
297 /*****************************************************************************
298 *Function name
299 * ltt_facility_close : close a facility, decrease its usage count,
300 * if usage count = 0, release the memory
301 *Input params
302 * f : facility that will be closed
303 *Return value
304 * int : usage count ?? status
305 ****************************************************************************/
306
307 int ltt_facility_close(LttFacility *f)
308 {
309 //release the memory it occupied
310 freeFacility(f);
311
312 return 0;
313 }
314
315 /*****************************************************************************
316 * Functions to release the memory occupied by the facility
317 ****************************************************************************/
318
319 void freeFacility(LttFacility * fac)
320 {
321 int i;
322 g_free(fac->name); //free facility name
323
324 //free event types
325 for(i=0;i<fac->event_number;i++){
326 freeEventtype(fac->events[i]);
327 }
328 g_free(fac->events);
329
330 //free all named types
331 freeAllNamedTypes(&(fac->all_named_types));
332
333 //free all unnamed types
334 freeAllUnamedTypes(&(fac->all_unnamed_types));
335
336 //free all fields
337 freeAllFields(&(fac->all_fields));
338
339 //free the facility itself
340 g_free(fac);
341 }
342
343 void freeEventtype(LttEventType * evType)
344 {
345 g_free(evType->name);
346 if(evType->description)
347 g_free(evType->description);
348 g_free(evType);
349 }
350
351 void freeAllNamedTypes(table * named_types)
352 {
353 int i;
354 for(i=0;i<named_types->keys.position;i++){
355 //free the name of the type
356 g_free((char*)(named_types->keys.array[i]));
357
358 //free type
359 freeLttType((LttType*)(named_types->values.array[i]));
360 }
361 table_dispose(named_types);
362 }
363
364 void freeAllUnamedTypes(sequence * unnamed_types)
365 {
366 int i;
367 for(i=0;i<unnamed_types->position;i++){
368 freeLttType((LttType*)(unnamed_types->array[i]));
369 }
370 sequence_dispose(unnamed_types);
371 }
372
373 void freeAllFields(sequence * all_fields)
374 {
375 int i;
376 for(i=0;i<all_fields->position;i++){
377 freeLttField((LttField*)(all_fields->array[i]));
378 }
379 sequence_dispose(all_fields);
380 }
381
382 //only free current type, not child types
383 void freeLttType(LttType * type)
384 {
385 int i;
386 if(type->element_name)
387 g_free(type->element_name);
388 if(type->fmt)
389 g_free(type->fmt);
390 if(type->enum_strings){
391 for(i=0;i<type->element_number;i++)
392 g_free(type->enum_strings[i]);
393 g_free(type->enum_strings);
394 }
395
396 if(type->element_type){
397 g_free(type->element_type);
398 }
399 g_free(type);
400 }
401
402 //only free the current field, not child fields
403 void freeLttField(LttField * fld)
404 {
405 if(fld->child)
406 g_free(fld->child);
407 g_free(fld);
408 }
409
410 /*****************************************************************************
411 *Function name
412 * ltt_facility_name : obtain the facility's name
413 *Input params
414 * f : the facility that will be closed
415 *Return value
416 * char * : the facility's name
417 ****************************************************************************/
418
419 char *ltt_facility_name(LttFacility *f)
420 {
421 return f->name;
422 }
423
424 /*****************************************************************************
425 *Function name
426 * ltt_facility_checksum : obtain the facility's checksum
427 *Input params
428 * f : the facility that will be closed
429 *Return value
430 * LttChecksum : the checksum of the facility
431 ****************************************************************************/
432
433 LttChecksum ltt_facility_checksum(LttFacility *f)
434 {
435 return f->checksum;
436 }
437
438 /*****************************************************************************
439 *Function name
440 * ltt_facility_base_id : obtain the facility base id
441 *Input params
442 * f : the facility
443 *Return value
444 * : the base id of the facility
445 ****************************************************************************/
446
447 unsigned ltt_facility_base_id(LttFacility *f)
448 {
449 return f->base_id;
450 }
451
452 /*****************************************************************************
453 *Function name
454 * ltt_facility_eventtype_number: obtain the number of the event types
455 *Input params
456 * f : the facility that will be closed
457 *Return value
458 * unsigned : the number of the event types
459 ****************************************************************************/
460
461 unsigned ltt_facility_eventtype_number(LttFacility *f)
462 {
463 return (unsigned)(f->event_number);
464 }
465
466 /*****************************************************************************
467 *Function name
468 * ltt_facility_eventtype_get: obtain the event type according to event id
469 * from 0 to event_number - 1
470 *Input params
471 * f : the facility that will be closed
472 *Return value
473 * LttEventType * : the event type required
474 ****************************************************************************/
475
476 LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
477 {
478 return f->events[i];
479 }
480
481 /*****************************************************************************
482 *Function name
483 * ltt_facility_eventtype_get_by_name
484 * : obtain the event type according to event name
485 * event name is unique in the facility
486 *Input params
487 * f : the facility that will be closed
488 * name : the name of the event
489 *Return value
490 * LttEventType * : the event type required
491 ****************************************************************************/
492
493 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, char *name)
494 {
495 int i;
496 LttEventType * ev;
497 for(i=0;i<f->event_number;i++){
498 ev = f->events[i];
499 if(strcmp(ev->name, name) == 0)break;
500 }
501
502 if(i==f->event_number) return NULL;
503 else return ev;
504 }
505
This page took 0.052354 seconds and 5 git commands to generate.