1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
3 * 2005 Mathieu Desnoyers
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28 #include <sys/types.h>
36 #include "ltt-private.h"
37 #include <ltt/facility.h>
45 /* search for the (named) type in the table, if it does not exist
47 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor_t
* td
);
49 /* construct directed acyclic graph for types, and tree for fields */
50 void construct_types_and_fields(LttFacility
* fac
, type_descriptor_t
* td
,
53 /* generate the facility according to the events belongin to it */
54 void generateFacility(LttFacility
* f
, facility_t
* fac
,
57 /* functions to release the memory occupied by a facility */
58 void freeFacility(LttFacility
* facility
);
59 void freeEventtype(LttEventType
* evType
);
60 void freeLttType(LttType
** type
);
61 void freeLttField(LttField
* fld
);
62 void freeLttNamedType(LttType
* type
);
65 /*****************************************************************************
67 * ltt_facility_open : open facilities
69 * t : the trace containing the facilities
70 * pathname : the path name of the facility
72 * Open the facility corresponding to the right checksum.
74 *returns 0 on success, 1 on error.
75 ****************************************************************************/
77 int ltt_facility_open(LttFacility
*f
, LttTrace
* t
, gchar
* pathname
)
83 unsigned long checksum
;
84 gchar buffer
[BUFFER_SIZE
];
85 gboolean generated
= FALSE
;
87 in
.buffer
= &(buffer
[0]);
89 in
.error
= error_callback
;
93 in
.fp
= fopen(in
.name
, "r");
95 g_warning("cannot open facility description file %s",
102 token
= getToken(&in
);
103 if(in
.type
== ENDFILE
) break;
105 if(g_ascii_strcasecmp(token
, "<")) in
.error(&in
,"not a facility file");
106 token
= getName(&in
);
108 if(g_ascii_strcasecmp("facility",token
) == 0) {
109 fac
= g_new(facility_t
, 1);
111 fac
->description
= NULL
;
112 sequence_init(&(fac
->events
));
113 table_init(&(fac
->named_types
));
114 sequence_init(&(fac
->unnamed_types
));
116 parseFacility(&in
, fac
);
118 //check if any namedType is not defined
119 checkNamedTypesImplemented(&fac
->named_types
);
121 generateChecksum(fac
->name
, &checksum
, &fac
->events
);
123 if(checksum
== f
->checksum
) {
124 generateFacility(f
, fac
, checksum
);
130 g_free(fac
->description
);
131 freeEvents(&fac
->events
);
132 sequence_dispose(&fac
->events
);
133 freeNamedType(&fac
->named_types
);
134 table_dispose(&fac
->named_types
);
135 freeTypes(&fac
->unnamed_types
);
136 sequence_dispose(&fac
->unnamed_types
);
138 if(generated
) break; /* use the first good match */
141 g_warning("facility token was expected in file %s", in
.name
);
152 g_warning("Cannot find facility %s, checksum 0x%X",
153 g_quark_to_string(f
->name
), f
->checksum
);
161 /*****************************************************************************
163 * generateFacility : generate facility, internal function
165 * facility : LttFacilty structure
166 * fac : facility structure
167 * checksum : checksum of the facility
168 ****************************************************************************/
170 void generateFacility(LttFacility
*f
, facility_t
*fac
, guint32 checksum
)
172 char * facilityName
= fac
->name
;
173 sequence_t
* events
= &fac
->events
;
175 //LttEventType * evType;
176 LttEventType
* event_type
;
180 g_assert(f
->name
== g_quark_from_string(facilityName
));
181 g_assert(f
->checksum
== checksum
);
183 //f->event_number = events->position;
185 //initialize inner structures
186 f
->events
= g_array_sized_new (FALSE
, TRUE
, sizeof(LttEventType
),
188 //f->events = g_new(LttEventType*,f->event_number);
189 f
->events
= g_array_set_size(f
->events
, events
->position
);
191 g_datalist_init(&f
->events_by_name
);
192 g_datalist_init(&f
->named_types
);
194 //f->named_types_number = fac->named_types.keys.position;
195 //f->named_types = g_array_sized_new (FALSE, TRUE, sizeof(LttType),
196 // fac->named_types.keys.position);
197 //f->named_types = g_new(LttType*, fac->named_types.keys.position);
198 //f->named_types = g_array_set_size(f->named_types,
199 // fac->named_types.keys.position);
201 //for each event, construct field tree and type graph
202 for(i
=0;i
<events
->position
;i
++){
203 event_type
= &g_array_index(f
->events
, LttEventType
, i
);
204 //evType = g_new(LttEventType,1);
205 //f->events[i] = evType;
208 g_quark_from_string(((event_t
*)(events
->array
[i
]))->name
);
210 g_datalist_id_set_data(&f
->events_by_name
, event_type
->name
,
213 event_type
->description
=
214 g_strdup(((event_t
*)(events
->array
[i
]))->description
);
216 field
= g_new(LttField
, 1);
217 event_type
->root_field
= field
;
218 event_type
->facility
= f
;
219 event_type
->index
= i
;
221 if(((event_t
*)(events
->array
[i
]))->type
!= NULL
){
222 // field->field_pos = 0;
223 type
= lookup_named_type(f
,((event_t
*)(events
->array
[i
]))->type
);
224 field
->field_type
= type
;
225 field
->offset_root
= 0;
226 field
->fixed_root
= FIELD_UNKNOWN
;
227 field
->offset_parent
= 0;
228 field
->fixed_parent
= FIELD_UNKNOWN
;
229 // field->base_address = NULL;
230 field
->field_size
= 0;
231 field
->fixed_size
= FIELD_UNKNOWN
;
232 field
->parent
= NULL
;
234 field
->current_element
= 0;
236 //construct field tree and type graph
237 construct_types_and_fields(f
,((event_t
*)(events
->array
[i
]))->type
,field
);
239 event_type
->root_field
= NULL
;
246 /*****************************************************************************
248 * construct_types_and_fields : construct field tree and type graph,
249 * internal recursion function
251 * fac : facility struct
252 * td : type descriptor
253 * root_field : root field of the event
254 ****************************************************************************/
257 void construct_types_and_fields(LttFacility
* fac
, type_descriptor_t
* td
,
261 type_descriptor_t
* tmpTd
;
267 fld
->field_type
->size
= td
->size
;
275 fld
->field_type
->size
= 0;
278 fld
->field_type
->size
= 0;
281 fld
->field_type
->element_number
= td
->labels
.position
;
282 fld
->field_type
->enum_strings
= g_new(GQuark
,td
->labels
.position
);
283 for(i
=0;i
<td
->labels
.position
;i
++){
284 fld
->field_type
->enum_strings
[i
]
285 = g_quark_from_string(((char*)(td
->labels
.array
[i
])));
287 fld
->field_type
->size
= td
->size
;
291 fld
->field_type
->element_number
= (unsigned)td
->size
;
293 fld
->field_type
->element_type
= g_new(LttType
*,1);
294 tmpTd
= td
->nested_type
;
295 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
296 fld
->child
= g_new(LttField
*, 1);
297 fld
->child
[0] = g_new(LttField
, 1);
299 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
300 fld
->child
[0]->offset_root
= 0;
301 fld
->child
[0]->fixed_root
= FIELD_UNKNOWN
;
302 fld
->child
[0]->offset_parent
= 0;
303 fld
->child
[0]->fixed_parent
= FIELD_UNKNOWN
;
304 fld
->child
[0]->field_size
= 0;
305 fld
->child
[0]->fixed_size
= FIELD_UNKNOWN
;
306 fld
->child
[0]->parent
= fld
;
307 fld
->child
[0]->child
= NULL
;
308 fld
->child
[0]->current_element
= 0;
309 construct_types_and_fields(fac
, tmpTd
, fld
->child
[0]);
314 fld
->field_type
->element_number
= td
->fields
.position
;
316 g_assert(fld
->field_type
->element_type
== NULL
);
317 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
319 fld
->child
= g_new(LttField
*, td
->fields
.position
);
320 for(i
=0;i
<td
->fields
.position
;i
++){
321 tmpTd
= ((field_t
*)(td
->fields
.array
[i
]))->type
;
323 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
324 fld
->child
[i
] = g_new(LttField
,1);
326 // fld->child[i]->field_pos = i;
327 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
329 fld
->child
[i
]->field_type
->element_name
330 = g_quark_from_string(((field_t
*)(td
->fields
.array
[i
]))->name
);
332 fld
->child
[i
]->offset_root
= 0;
333 fld
->child
[i
]->fixed_root
= FIELD_UNKNOWN
;
334 fld
->child
[i
]->offset_parent
= 0;
335 fld
->child
[i
]->fixed_parent
= FIELD_UNKNOWN
;
336 fld
->child
[i
]->field_size
= 0;
337 fld
->child
[i
]->fixed_size
= FIELD_UNKNOWN
;
338 fld
->child
[i
]->parent
= fld
;
339 fld
->child
[i
]->child
= NULL
;
340 fld
->child
[i
]->current_element
= 0;
341 construct_types_and_fields(fac
, tmpTd
, fld
->child
[i
]);
346 g_error("construct_types_and_fields : unknown type");
355 void construct_types_and_fields(LttFacility
* fac
, type_descriptor
* td
,
359 type_descriptor
* tmpTd
;
361 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
362 // fld->field_size = 0;
363 // else fld->field_size = -1;
365 if(td
->type
== LTT_ENUM
){
366 fld
->field_type
->element_number
= td
->labels
.position
;
367 fld
->field_type
->enum_strings
= g_new(GQuark
,td
->labels
.position
);
368 for(i
=0;i
<td
->labels
.position
;i
++){
369 fld
->field_type
->enum_strings
[i
]
370 = g_quark_from_string(((char*)(td
->labels
.array
[i
])));
372 }else if(td
->type
== LTT_ARRAY
|| td
->type
== LTT_SEQUENCE
){
373 if(td
->type
== LTT_ARRAY
)
374 fld
->field_type
->element_number
= (unsigned)td
->size
;
375 fld
->field_type
->element_type
= g_new(LttType
*,1);
376 tmpTd
= td
->nested_type
;
377 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
378 fld
->child
= g_new(LttField
*, 1);
379 fld
->child
[0] = g_new(LttField
, 1);
381 // fld->child[0]->field_pos = 0;
382 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
383 fld
->child
[0]->offset_root
= fld
->offset_root
;
384 fld
->child
[0]->fixed_root
= fld
->fixed_root
;
385 fld
->child
[0]->offset_parent
= 0;
386 fld
->child
[0]->fixed_parent
= 1;
387 // fld->child[0]->base_address = NULL;
388 fld
->child
[0]->field_size
= 0;
389 fld
->child
[0]->field_fixed
= -1;
390 fld
->child
[0]->parent
= fld
;
391 fld
->child
[0]->child
= NULL
;
392 fld
->child
[0]->current_element
= 0;
393 construct_types_and_fields(fac
, tmpTd
, fld
->child
[0]);
394 }else if(td
->type
== LTT_STRUCT
){
395 fld
->field_type
->element_number
= td
->fields
.position
;
397 if(fld
->field_type
->element_type
== NULL
){
398 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
404 fld
->child
= g_new(LttField
*, td
->fields
.position
);
405 for(i
=0;i
<td
->fields
.position
;i
++){
406 tmpTd
= ((type_fields
*)(td
->fields
.array
[i
]))->type
;
409 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
410 fld
->child
[i
] = g_new(LttField
,1);
412 fld
->child
[i
]->field_pos
= i
;
413 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
416 fld
->child
[i
]->field_type
->element_name
417 = g_quark_from_string(((type_fields
*)(td
->fields
.array
[i
]))->name
);
420 fld
->child
[i
]->offset_root
= -1;
421 fld
->child
[i
]->fixed_root
= -1;
422 fld
->child
[i
]->offset_parent
= -1;
423 fld
->child
[i
]->fixed_parent
= -1;
424 // fld->child[i]->base_address = NULL;
425 fld
->child
[i
]->field_size
= 0;
426 fld
->child
[i
]->field_fixed
= -1;
427 fld
->child
[i
]->parent
= fld
;
428 fld
->child
[i
]->child
= NULL
;
429 fld
->child
[i
]->current_element
= 0;
430 construct_types_and_fields(fac
, tmpTd
, fld
->child
[i
]);
436 /*****************************************************************************
438 * lookup_named_type: search named type in the table
441 * fac : facility struct
442 * td : type descriptor
444 * : either find the named type, or create a new LttType
445 ****************************************************************************/
447 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor_t
* td
)
449 LttType
*type
= NULL
;
452 if(td
->type_name
!= NULL
) {
454 name
= g_quark_from_string(td
->type_name
);
456 type
= g_datalist_id_get_data(&fac
->named_types
, name
);
460 /* Create the type */
461 type
= g_new(LttType
,1);
462 type
->type_name
= name
;
463 type
->type_class
= td
->type
;
464 if(td
->fmt
) type
->fmt
= g_strdup(td
->fmt
);
465 else type
->fmt
= NULL
;
466 type
->size
= td
->size
;
467 type
->enum_strings
= NULL
;
468 type
->element_type
= NULL
;
469 type
->element_number
= 0;
471 if(td
->type_name
!= NULL
)
472 g_datalist_id_set_data_full(&fac
->named_types
, name
,
473 type
, (GDestroyNotify
)freeLttNamedType
);
479 /*****************************************************************************
481 * ltt_facility_close : close a facility, decrease its usage count,
482 * if usage count = 0, release the memory
484 * f : facility that will be closed
485 ****************************************************************************/
487 void ltt_facility_close(LttFacility
*f
)
489 //release the memory it occupied
493 /*****************************************************************************
494 * Functions to release the memory occupied by the facility
495 ****************************************************************************/
497 void freeFacility(LttFacility
* fac
)
502 for(i
=0; i
<fac
->events
->len
; i
++) {
503 et
= &g_array_index (fac
->events
, LttEventType
, i
);
506 g_array_free(fac
->events
, TRUE
);
508 g_datalist_clear(&fac
->named_types
);
512 void freeEventtype(LttEventType
* evType
)
515 if(evType
->description
)
516 g_free(evType
->description
);
517 if(evType
->root_field
){
518 root_type
= evType
->root_field
->field_type
;
519 freeLttField(evType
->root_field
);
520 freeLttType(&root_type
);
524 void freeLttNamedType(LttType
* type
)
529 void freeLttType(LttType
** type
)
532 if(*type
== NULL
) return;
533 if((*type
)->type_name
!= 0) return; //this is a named type.
534 //if((*type)->type_name){
535 // return; //this is a named type
538 g_free((*type
)->fmt
);
539 if((*type
)->enum_strings
){
540 g_free((*type
)->enum_strings
);
543 if((*type
)->element_type
){
544 for(i
=0;i
<(*type
)->element_number
;i
++)
545 freeLttType(&((*type
)->element_type
[i
]));
546 g_free((*type
)->element_type
);
552 void freeLttField(LttField
* fld
)
558 if(fld
->field_type
->type_class
== LTT_ARRAY
||
559 fld
->field_type
->type_class
== LTT_SEQUENCE
){
561 }else if(fld
->field_type
->type_class
== LTT_STRUCT
){
562 size
= fld
->field_type
->element_number
;
567 for(i
=0; i
<size
; i
++){
568 if(fld
->child
[i
])freeLttField(fld
->child
[i
]);
575 /*****************************************************************************
577 * ltt_facility_name : obtain the facility's name
581 * GQuark : the facility's name
582 ****************************************************************************/
584 GQuark
ltt_facility_name(LttFacility
*f
)
589 /*****************************************************************************
591 * ltt_facility_checksum : obtain the facility's checksum
595 * : the checksum of the facility
596 ****************************************************************************/
598 guint32
ltt_facility_checksum(LttFacility
*f
)
603 /*****************************************************************************
605 * ltt_facility_base_id : obtain the facility base id
609 * : the base id of the facility
610 ****************************************************************************/
612 guint
ltt_facility_id(LttFacility
*f
)
617 /*****************************************************************************
619 * ltt_facility_eventtype_number: obtain the number of the event types
621 * f : the facility that will be closed
623 * : the number of the event types
624 ****************************************************************************/
626 guint8
ltt_facility_eventtype_number(LttFacility
*f
)
628 return (f
->events
->len
);
631 /*****************************************************************************
633 * ltt_facility_eventtype_get: obtain the event type according to event id
634 * from 0 to event_number - 1
636 * f : the facility that will be closed
638 * LttEventType * : the event type required
639 ****************************************************************************/
641 LttEventType
*ltt_facility_eventtype_get(LttFacility
*f
, guint8 i
)
643 if(!f
->exists
) return NULL
;
645 g_assert(i
< f
->events
->len
);
646 return &g_array_index(f
->events
, LttEventType
, i
);
649 /*****************************************************************************
651 * ltt_facility_eventtype_get_by_name
652 * : obtain the event type according to event name
653 * event name is unique in the facility
656 * name : the name of the event
658 * LttEventType * : the event type required
659 ****************************************************************************/
661 LttEventType
*ltt_facility_eventtype_get_by_name(LttFacility
*f
, GQuark name
)
663 LttEventType
*et
= g_datalist_id_get_data(&f
->events_by_name
, name
);
This page took 0.043673 seconds and 4 git commands to generate.