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