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
* td
);
49 /* construct directed acyclic graph for types, and tree for fields */
50 void constructTypeAndFields(LttFacility
* fac
,type_descriptor
* td
,
53 /* generate the facility according to the events belongin to it */
54 void generateFacility(LttFacility
* f
, facility_t
* fac
,
55 LttChecksum checksum
);
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 *returns 0 on success, 1 on error.
73 ****************************************************************************/
75 int ltt_facility_open(LttFacility
*f
, LttTrace
* t
, gchar
* pathname
)
82 GError
* error
= NULL
;
83 gchar buffer
[BUFFER_SIZE
];
85 in
.buffer
= &(buffer
[0]);
87 in
.error
= error_callback
;
90 in
.fd
= g_open(in
.name
, O_RDONLY
, 0);
92 g_warning("cannot open facility description file %s",
97 in
.channel
= g_io_channel_unix_new(in
.fd
);
101 token
= getToken(&in
);
102 if(in
.type
== ENDFILE
) break;
104 if(g_ascii_strcasecmp(token
, "<")) in
.error(&in
,"not a facility file");
105 token
= getName(&in
);
107 if(g_ascii_strcasecmp("facility",token
) == 0) {
108 fac
= g_new(facility_t
, 1);
110 fac
->description
= NULL
;
111 sequence_init(&(fac
->events
));
112 table_init(&(fac
->named_types
));
113 sequence_init(&(fac
->unnamed_types
));
115 parseFacility(&in
, fac
);
117 //check if any namedType is not defined
118 g_assert(checkNamedTypesImplemented(&fac
->named_types
) == 0);
120 g_assert(generateChecksum(fac
->name
, &checksum
, &fac
->events
) == 0);
122 generateFacility(f
, fac
, checksum
);
125 g_free(fac
->description
);
126 freeEvents(&fac
->events
);
127 sequence_dispose(&fac
->events
);
128 freeNamedType(&fac
->named_types
);
129 table_dispose(&fac
->named_types
);
130 freeTypes(&fac
->unnamed_types
);
131 sequence_dispose(&fac
->unnamed_types
);
135 g_warning("facility token was expected in file %s", in
.name
);
141 g_io_channel_shutdown(in
.channel
, FALSE
, &error
); /* No flush */
143 g_warning("Can not close file: \n%s\n", error
->message
);
151 /*****************************************************************************
153 * generateFacility : generate facility, internal function
155 * facility : LttFacilty structure
156 * fac : facility structure
157 * checksum : checksum of the facility
158 ****************************************************************************/
160 void generateFacility(LttFacility
*f
, facility_t
*fac
,LttChecksum checksum
)
162 char * facilityName
= fac
->name
;
163 sequence
* events
= &fac
->events
;
165 //LttEventType * evType;
166 LttEventType
* event_type
;
170 g_assert(f
->name
== g_quark_from_string(facilityName
));
171 g_assert(f
->checksum
== checksum
);
173 //f->event_number = events->position;
175 //initialize inner structures
176 f
->events
= g_array_sized_new (FALSE
, TRUE
, sizeof(LttEventType
),
178 //f->events = g_new(LttEventType*,f->event_number);
179 f
->events
= g_array_set_size(f
->events
, events
->position
);
181 g_datalist_init(f
->events_by_name
);
182 g_datalist_init(f
->named_types
);
184 //f->named_types_number = fac->named_types.keys.position;
185 //f->named_types = g_array_sized_new (FALSE, TRUE, sizeof(LttType),
186 // fac->named_types.keys.position);
187 //f->named_types = g_new(LttType*, fac->named_types.keys.position);
188 //f->named_types = g_array_set_size(f->named_types,
189 // fac->named_types.keys.position);
191 //for each event, construct field tree and type graph
192 for(i
=0;i
<events
->position
;i
++){
193 event_type
= &g_array_index(f
->events
, LttEventType
, i
);
194 //evType = g_new(LttEventType,1);
195 //f->events[i] = evType;
198 g_quark_from_string(((event_t
*)(events
->array
[i
]))->name
);
200 g_datalist_set_data(f
->events_by_name
, event_type
->name
,
203 event_type
->description
=
204 g_strdup(((event_t
*)(events
->array
[i
]))->description
);
206 field
= g_new(LttField
, 1);
207 event_type
->root_field
= field
;
208 event_type
->facility
= f
;
209 event_type
->index
= i
;
211 if(((event_t
*)(events
->array
[i
]))->type
!= NULL
){
212 field
->field_pos
= 0;
213 type
= lookup_named_type(f
,((event_t
*)(events
->array
[i
]))->type
);
214 field
->field_type
= type
;
215 field
->offset_root
= 0;
216 field
->fixed_root
= 1;
217 field
->offset_parent
= 0;
218 field
->fixed_parent
= 1;
219 // field->base_address = NULL;
220 field
->field_size
= 0;
221 field
->field_fixed
= -1;
222 field
->parent
= NULL
;
224 field
->current_element
= 0;
226 //construct field tree and type graph
227 constructTypeAndFields(f
,((event_t
*)(events
->array
[i
]))->type
,field
);
229 evType
->root_field
= NULL
;
236 /*****************************************************************************
238 * constructTypeAndFields : construct field tree and type graph,
239 * internal recursion function
241 * fac : facility struct
242 * td : type descriptor
243 * root_field : root field of the event
244 ****************************************************************************/
246 void constructTypeAndFields(LttFacility
* fac
, type_descriptor
* td
,
250 type_descriptor
* tmpTd
;
252 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
253 // fld->field_size = 0;
254 // else fld->field_size = -1;
256 if(td
->type
== LTT_ENUM
){
257 fld
->field_type
->element_number
= td
->labels
.position
;
258 fld
->field_type
->enum_strings
= g_new(GQuark
,td
->labels
.position
);
259 for(i
=0;i
<td
->labels
.position
;i
++){
260 fld
->field_type
->enum_strings
[i
]
261 = g_quark_from_string(((char*)(td
->labels
.array
[i
])));
263 }else if(td
->type
== LTT_ARRAY
|| td
->type
== LTT_SEQUENCE
){
264 if(td
->type
== LTT_ARRAY
)
265 fld
->field_type
->element_number
= (unsigned)td
->size
;
266 fld
->field_type
->element_type
= g_new(LttType
*,1);
267 tmpTd
= td
->nested_type
;
268 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
269 fld
->child
= g_new(LttField
*, 1);
270 fld
->child
[0] = g_new(LttField
, 1);
272 fld
->child
[0]->field_pos
= 0;
273 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
274 fld
->child
[0]->offset_root
= fld
->offset_root
;
275 fld
->child
[0]->fixed_root
= fld
->fixed_root
;
276 fld
->child
[0]->offset_parent
= 0;
277 fld
->child
[0]->fixed_parent
= 1;
278 // fld->child[0]->base_address = NULL;
279 fld
->child
[0]->field_size
= 0;
280 fld
->child
[0]->field_fixed
= -1;
281 fld
->child
[0]->parent
= fld
;
282 fld
->child
[0]->child
= NULL
;
283 fld
->child
[0]->current_element
= 0;
284 constructTypeAndFields(fac
, tmpTd
, fld
->child
[0]);
285 }else if(td
->type
== LTT_STRUCT
){
286 fld
->field_type
->element_number
= td
->fields
.position
;
288 if(fld
->field_type
->element_type
== NULL
){
289 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
295 fld
->child
= g_new(LttField
*, td
->fields
.position
);
296 for(i
=0;i
<td
->fields
.position
;i
++){
297 tmpTd
= ((type_fields
*)(td
->fields
.array
[i
]))->type
;
300 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
301 fld
->child
[i
] = g_new(LttField
,1);
303 fld
->child
[i
]->field_pos
= i
;
304 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
307 fld
->child
[i
]->field_type
->element_name
308 = g_quark_from_string(((type_fields
*)(td
->fields
.array
[i
]))->name
);
311 fld
->child
[i
]->offset_root
= -1;
312 fld
->child
[i
]->fixed_root
= -1;
313 fld
->child
[i
]->offset_parent
= -1;
314 fld
->child
[i
]->fixed_parent
= -1;
315 // fld->child[i]->base_address = NULL;
316 fld
->child
[i
]->field_size
= 0;
317 fld
->child
[i
]->field_fixed
= -1;
318 fld
->child
[i
]->parent
= fld
;
319 fld
->child
[i
]->child
= NULL
;
320 fld
->child
[i
]->current_element
= 0;
321 constructTypeAndFields(fac
, tmpTd
, fld
->child
[i
]);
327 /*****************************************************************************
329 * lookup_named_type: search named type in the table
332 * fac : facility struct
333 * td : type descriptor
335 * : either find the named type, or create a new LttType
336 ****************************************************************************/
338 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor
* td
)
340 GQuark name
= g_quark_from_string(td
->type_name
);
342 LttType
*type
= g_datalist_get_data(fac
->named_types_by_name
, name
);
345 type
= g_new(LttType
,1);
346 type
->type_name
= name
;
347 g_datalist_set_data_full(fac
->named_types
, name
,
348 type
, freeLttNamedType
);
349 type
->type_class
= td
->type
;
350 if(td
->fmt
) type
->fmt
= g_strdup(td
->fmt
);
351 else type
->fmt
= NULL
;
352 type
->size
= td
->size
;
353 type
->enum_strings
= NULL
;
354 type
->element_type
= NULL
;
355 type
->element_number
= 0;
362 /*****************************************************************************
364 * ltt_facility_close : close a facility, decrease its usage count,
365 * if usage count = 0, release the memory
367 * f : facility that will be closed
368 ****************************************************************************/
370 void ltt_facility_close(LttFacility
*f
)
372 //release the memory it occupied
376 /*****************************************************************************
377 * Functions to release the memory occupied by the facility
378 ****************************************************************************/
380 void freeFacility(LttFacility
* fac
)
385 for(i
=0; i
<fac
->events
->len
; i
++) {
386 et
= &g_array_index (fac
->events
, LttEventType
, i
);
389 g_array_free(fac
->events
);
391 g_datalist_clear(fac
->named_types
);
395 void freeEventtype(LttEventType
* evType
)
398 if(evType
->description
)
399 g_free(evType
->description
);
400 if(evType
->root_field
){
401 root_type
= evType
->root_field
->field_type
;
402 freeLttField(evType
->root_field
);
403 freeLttType(&root_type
);
407 void freeLttNamedType(LttType
* type
)
412 void freeLttType(LttType
** type
)
415 if(*type
== NULL
) return;
416 //if((*type)->type_name){
417 // return; //this is a named type
420 g_free((*type
)->fmt
);
421 if((*type
)->enum_strings
){
422 g_free((*type
)->enum_strings
);
425 if((*type
)->element_type
){
426 for(i
=0;i
<(*type
)->element_number
;i
++)
427 freeLttType(&((*type
)->element_type
[i
]));
428 g_free((*type
)->element_type
);
434 void freeLttField(LttField
* fld
)
440 if(fld
->field_type
->type_class
== LTT_ARRAY
||
441 fld
->field_type
->type_class
== LTT_SEQUENCE
){
443 }else if(fld
->field_type
->type_class
== LTT_STRUCT
){
444 size
= fld
->field_type
->element_number
;
449 for(i
=0; i
<size
; i
++){
450 if(fld
->child
[i
])freeLttField(fld
->child
[i
]);
457 /*****************************************************************************
459 * ltt_facility_name : obtain the facility's name
463 * GQuark : the facility's name
464 ****************************************************************************/
466 GQuark
ltt_facility_name(LttFacility
*f
)
471 /*****************************************************************************
473 * ltt_facility_checksum : obtain the facility's checksum
477 * LttChecksum : the checksum of the facility
478 ****************************************************************************/
480 LttChecksum
ltt_facility_checksum(LttFacility
*f
)
485 /*****************************************************************************
487 * ltt_facility_base_id : obtain the facility base id
491 * : the base id of the facility
492 ****************************************************************************/
494 guint
ltt_facility_id(LttFacility
*f
)
499 /*****************************************************************************
501 * ltt_facility_eventtype_number: obtain the number of the event types
503 * f : the facility that will be closed
505 * : the number of the event types
506 ****************************************************************************/
508 guint
ltt_facility_eventtype_number(LttFacility
*f
)
510 return (f
->events
->len
);
513 /*****************************************************************************
515 * ltt_facility_eventtype_get: obtain the event type according to event id
516 * from 0 to event_number - 1
518 * f : the facility that will be closed
520 * LttEventType * : the event type required
521 ****************************************************************************/
523 LttEventType
*ltt_facility_eventtype_get(LttFacility
*f
, guint8 i
)
525 g_assert(i
< f
->events
->len
);
526 return &g_array_index(f
->events
, LttEventType
, i
);
529 /*****************************************************************************
531 * ltt_facility_eventtype_get_by_name
532 * : obtain the event type according to event name
533 * event name is unique in the facility
536 * name : the name of the event
538 * LttEventType * : the event type required
539 ****************************************************************************/
541 LttEventType
*ltt_facility_eventtype_get_by_name(LttFacility
*f
, GQuark name
)
543 LttEventType
*et
= g_datalist_get_data(fac
->events_by_name
, name
);
This page took 0.04812 seconds and 5 git commands to generate.