1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
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;
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.
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,
27 #include <sys/types.h>
35 #include "ltt-private.h"
36 #include <ltt/facility.h>
44 /* search for the (named) type in the table, if it does not exist
46 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor
* td
);
48 /* construct directed acyclic graph for types, and tree for fields */
49 void constructTypeAndFields(LttFacility
* fac
,type_descriptor
* td
,
52 /* generate the facility according to the events belongin to it */
53 void generateFacility(LttFacility
* f
, facility_t
* fac
,
54 LttChecksum checksum
);
56 /* functions to release the memory occupied by a facility */
57 void freeFacility(LttFacility
* facility
);
58 void freeEventtype(LttEventType
* evType
);
59 void freeLttType(LttType
** type
);
60 void freeLttField(LttField
* fld
);
61 void freeLttNamedType(LttType
* type
);
64 /*****************************************************************************
66 * ltt_facility_open : open facilities
68 * t : the trace containing the facilities
69 * pathname : the path name of the facility
70 ****************************************************************************/
72 void ltt_facility_open(LttTrace
* t
, gchar
* pathname
)
80 GError
* error
= NULL
;
81 gchar buffer
[BUFFER_SIZE
];
83 in
.buffer
= &(buffer
[0]);
85 in
.error
= error_callback
;
88 in
.fd
= g_open(in
.name
, O_RDONLY
, 0);
89 if(in
.fd
< 0 ) in
.error(&in
,"cannot open input file");
91 in
.channel
= g_io_channel_unix_new(in
.fd
);
95 token
= getToken(&in
);
96 if(in
.type
== ENDFILE
) break;
98 if(g_ascii_strcasecmp(token
, "<")) in
.error(&in
,"not a facility file");
101 if(g_ascii_strcasecmp("facility",token
) == 0) {
102 fac
= g_new(facility_t
, 1);
104 fac
->description
= NULL
;
105 sequence_init(&(fac
->events
));
106 table_init(&(fac
->named_types
));
107 sequence_init(&(fac
->unnamed_types
));
109 parseFacility(&in
, fac
);
111 //check if any namedType is not defined
112 g_assert(checkNamedTypesImplemented(&fac
->named_types
) == 0);
114 g_assert(generateChecksum(fac
->name
, &checksum
, &fac
->events
) == 0);
116 f
= g_new(LttFacility
,1);
118 generateFacility(f
, fac
, checksum
);
120 t
->facility_number
++;
121 g_ptr_array_add(t
->facilities
,f
);
124 g_free(fac
->description
);
125 freeEvents(&fac
->events
);
126 sequence_dispose(&fac
->events
);
127 freeNamedType(&fac
->named_types
);
128 table_dispose(&fac
->named_types
);
129 freeTypes(&fac
->unnamed_types
);
130 sequence_dispose(&fac
->unnamed_types
);
133 else in
.error(&in
,"facility token was expected");
136 g_io_channel_shutdown(in
.channel
, FALSE
, &error
); /* No flush */
138 g_warning("Can not close file: \n%s\n", error
->message
);
146 /*****************************************************************************
148 * generateFacility : generate facility, internal function
150 * facility : LttFacilty structure
151 * fac : facility structure
152 * checksum : checksum of the facility
153 ****************************************************************************/
155 void generateFacility(LttFacility
*f
, facility_t
*fac
,LttChecksum checksum
)
157 char * facilityName
= fac
->name
;
158 sequence
* events
= &fac
->events
;
160 LttEventType
* evType
;
164 f
->name
= g_strdup(facilityName
);
165 f
->event_number
= events
->position
;
166 f
->checksum
= checksum
;
168 //initialize inner structures
169 f
->events
= g_new(LttEventType
*,f
->event_number
);
170 f
->named_types_number
= fac
->named_types
.keys
.position
;
171 f
->named_types
= g_new(LttType
*, fac
->named_types
.keys
.position
);
172 for(i
=0;i
<fac
->named_types
.keys
.position
;i
++) f
->named_types
[i
] = NULL
;
174 //for each event, construct field tree and type graph
175 for(i
=0;i
<events
->position
;i
++){
176 evType
= g_new(LttEventType
,1);
177 f
->events
[i
] = evType
;
179 evType
->name
= g_strdup(((event_t
*)(events
->array
[i
]))->name
);
180 evType
->description
=g_strdup(((event_t
*)(events
->array
[i
]))->description
);
182 field
= g_new(LttField
, 1);
183 evType
->root_field
= field
;
184 evType
->facility
= f
;
187 if(((event_t
*)(events
->array
[i
]))->type
!= NULL
){
188 field
->field_pos
= 0;
189 type
= lookup_named_type(f
,((event_t
*)(events
->array
[i
]))->type
);
190 field
->field_type
= type
;
191 field
->offset_root
= 0;
192 field
->fixed_root
= 1;
193 field
->offset_parent
= 0;
194 field
->fixed_parent
= 1;
195 // field->base_address = NULL;
196 field
->field_size
= 0;
197 field
->field_fixed
= -1;
198 field
->parent
= NULL
;
200 field
->current_element
= 0;
202 //construct field tree and type graph
203 constructTypeAndFields(f
,((event_t
*)(events
->array
[i
]))->type
,field
);
205 evType
->root_field
= NULL
;
212 /*****************************************************************************
214 * constructTypeAndFields : construct field tree and type graph,
215 * internal recursion function
217 * fac : facility struct
218 * td : type descriptor
219 * root_field : root field of the event
220 ****************************************************************************/
222 void constructTypeAndFields(LttFacility
* fac
,type_descriptor
* td
,
226 type_descriptor
* tmpTd
;
228 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
229 // fld->field_size = 0;
230 // else fld->field_size = -1;
232 if(td
->type
== LTT_ENUM
){
233 fld
->field_type
->element_number
= td
->labels
.position
;
234 fld
->field_type
->enum_strings
= g_new(char*,td
->labels
.position
);
235 for(i
=0;i
<td
->labels
.position
;i
++){
236 fld
->field_type
->enum_strings
[i
]
237 = g_strdup(((char*)(td
->labels
.array
[i
])));
239 }else if(td
->type
== LTT_ARRAY
|| td
->type
== LTT_SEQUENCE
){
240 if(td
->type
== LTT_ARRAY
)
241 fld
->field_type
->element_number
= (unsigned)td
->size
;
242 fld
->field_type
->element_type
= g_new(LttType
*,1);
243 tmpTd
= td
->nested_type
;
244 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
245 fld
->child
= g_new(LttField
*, 1);
246 fld
->child
[0] = g_new(LttField
, 1);
248 fld
->child
[0]->field_pos
= 0;
249 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
250 fld
->child
[0]->offset_root
= fld
->offset_root
;
251 fld
->child
[0]->fixed_root
= fld
->fixed_root
;
252 fld
->child
[0]->offset_parent
= 0;
253 fld
->child
[0]->fixed_parent
= 1;
254 // fld->child[0]->base_address = NULL;
255 fld
->child
[0]->field_size
= 0;
256 fld
->child
[0]->field_fixed
= -1;
257 fld
->child
[0]->parent
= fld
;
258 fld
->child
[0]->child
= NULL
;
259 fld
->child
[0]->current_element
= 0;
260 constructTypeAndFields(fac
, tmpTd
, fld
->child
[0]);
261 }else if(td
->type
== LTT_STRUCT
){
262 fld
->field_type
->element_number
= td
->fields
.position
;
264 if(fld
->field_type
->element_type
== NULL
){
265 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
271 fld
->child
= g_new(LttField
*, td
->fields
.position
);
272 for(i
=0;i
<td
->fields
.position
;i
++){
273 tmpTd
= ((type_fields
*)(td
->fields
.array
[i
]))->type
;
276 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
277 fld
->child
[i
] = g_new(LttField
,1);
279 fld
->child
[i
]->field_pos
= i
;
280 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
283 fld
->child
[i
]->field_type
->element_name
284 = g_strdup(((type_fields
*)(td
->fields
.array
[i
]))->name
);
287 fld
->child
[i
]->offset_root
= -1;
288 fld
->child
[i
]->fixed_root
= -1;
289 fld
->child
[i
]->offset_parent
= -1;
290 fld
->child
[i
]->fixed_parent
= -1;
291 // fld->child[i]->base_address = NULL;
292 fld
->child
[i
]->field_size
= 0;
293 fld
->child
[i
]->field_fixed
= -1;
294 fld
->child
[i
]->parent
= fld
;
295 fld
->child
[i
]->child
= NULL
;
296 fld
->child
[i
]->current_element
= 0;
297 constructTypeAndFields(fac
, tmpTd
, fld
->child
[i
]);
303 /*****************************************************************************
305 * lookup_named_type: search named type in the table
308 * fac : facility struct
309 * td : type descriptor
311 * : either find the named type, or create a new LttType
312 ****************************************************************************/
314 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor
* td
)
316 LttType
* lttType
= NULL
;
321 for(i
=0;i
<fac
->named_types_number
; i
++){
322 if(fac
->named_types
[i
] == NULL
) break;
323 name
= fac
->named_types
[i
]->type_name
;
324 if(g_ascii_strcasecmp(name
, td
->type_name
)==0){
325 lttType
= fac
->named_types
[i
];
326 // if(lttType->element_name) g_free(lttType->element_name);
327 // lttType->element_name = NULL;
334 lttType
= g_new(LttType
,1);
335 lttType
->type_class
= td
->type
;
336 if(td
->fmt
) lttType
->fmt
= g_strdup(td
->fmt
);
337 else lttType
->fmt
= NULL
;
338 lttType
->size
= td
->size
;
339 lttType
->enum_strings
= NULL
;
340 lttType
->element_type
= NULL
;
341 lttType
->element_number
= 0;
342 lttType
->element_name
= NULL
;
344 lttType
->type_name
= g_strdup(td
->type_name
);
345 fac
->named_types
[i
] = lttType
; /* i is initialized, checked. */
348 lttType
->type_name
= NULL
;
356 /*****************************************************************************
358 * ltt_facility_close : close a facility, decrease its usage count,
359 * if usage count = 0, release the memory
361 * f : facility that will be closed
363 * int : usage count ?? status
364 ****************************************************************************/
366 int ltt_facility_close(LttFacility
*f
)
368 //release the memory it occupied
374 /*****************************************************************************
375 * Functions to release the memory occupied by the facility
376 ****************************************************************************/
378 void freeFacility(LttFacility
* fac
)
381 g_free(fac
->name
); //free facility name
384 for(i
=0;i
<fac
->event_number
;i
++){
385 freeEventtype(fac
->events
[i
]);
389 //free all named types
390 for(i
=0;i
<fac
->named_types_number
;i
++){
391 freeLttNamedType(fac
->named_types
[i
]);
392 fac
->named_types
[i
] = NULL
;
394 g_free(fac
->named_types
);
396 //free the facility itself
400 void freeEventtype(LttEventType
* evType
)
403 g_free(evType
->name
);
404 if(evType
->description
)
405 g_free(evType
->description
);
406 if(evType
->root_field
){
407 root_type
= evType
->root_field
->field_type
;
408 freeLttField(evType
->root_field
);
409 freeLttType(&root_type
);
415 void freeLttNamedType(LttType
* type
)
417 g_free(type
->type_name
);
418 type
->type_name
= NULL
;
422 void freeLttType(LttType
** type
)
425 if(*type
== NULL
) return;
426 if((*type
)->type_name
){
427 return; //this is a named type
429 if((*type
)->element_name
)
430 g_free((*type
)->element_name
);
432 g_free((*type
)->fmt
);
433 if((*type
)->enum_strings
){
434 for(i
=0;i
<(*type
)->element_number
;i
++)
435 g_free((*type
)->enum_strings
[i
]);
436 g_free((*type
)->enum_strings
);
439 if((*type
)->element_type
){
440 for(i
=0;i
<(*type
)->element_number
;i
++)
441 freeLttType(&((*type
)->element_type
[i
]));
442 g_free((*type
)->element_type
);
448 void freeLttField(LttField
* fld
)
454 if(fld
->field_type
->type_class
== LTT_ARRAY
||
455 fld
->field_type
->type_class
== LTT_SEQUENCE
){
457 }else if(fld
->field_type
->type_class
== LTT_STRUCT
){
458 size
= fld
->field_type
->element_number
;
463 for(i
=0; i
<size
; i
++){
464 if(fld
->child
[i
])freeLttField(fld
->child
[i
]);
471 /*****************************************************************************
473 * ltt_facility_name : obtain the facility's name
475 * f : the facility that will be closed
477 * char * : the facility's name
478 ****************************************************************************/
480 gchar
*ltt_facility_name(LttFacility
*f
)
485 /*****************************************************************************
487 * ltt_facility_checksum : obtain the facility's checksum
489 * f : the facility that will be closed
491 * LttChecksum : the checksum of the facility
492 ****************************************************************************/
494 LttChecksum
ltt_facility_checksum(LttFacility
*f
)
499 /*****************************************************************************
501 * ltt_facility_base_id : obtain the facility base id
505 * : the base id of the facility
506 ****************************************************************************/
508 unsigned ltt_facility_base_id(LttFacility
*f
)
513 /*****************************************************************************
515 * ltt_facility_eventtype_number: obtain the number of the event types
517 * f : the facility that will be closed
519 * unsigned : the number of the event types
520 ****************************************************************************/
522 unsigned ltt_facility_eventtype_number(LttFacility
*f
)
524 return (f
->event_number
);
527 /*****************************************************************************
529 * ltt_facility_eventtype_get: obtain the event type according to event id
530 * from 0 to event_number - 1
532 * f : the facility that will be closed
534 * LttEventType * : the event type required
535 ****************************************************************************/
537 LttEventType
*ltt_facility_eventtype_get(LttFacility
*f
, unsigned i
)
542 /*****************************************************************************
544 * ltt_facility_eventtype_get_by_name
545 * : obtain the event type according to event name
546 * event name is unique in the facility
549 * name : the name of the event
551 * LttEventType * : the event type required
552 ****************************************************************************/
554 LttEventType
*ltt_facility_eventtype_get_by_name(LttFacility
*f
, gchar
*name
)
557 LttEventType
* ev
= NULL
;
559 for(i
=0;i
<f
->event_number
;i
++){
560 LttEventType
*iter_ev
= f
->events
[i
];
561 if(g_ascii_strcasecmp(iter_ev
->name
, name
) == 0) {
This page took 0.042052 seconds and 4 git commands to generate.