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