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,
25 #include "ltt-private.h"
26 #include <ltt/facility.h>
28 /* search for the (named) type in the table, if it does not exist
30 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor
* td
);
32 /* construct directed acyclic graph for types, and tree for fields */
33 void constructTypeAndFields(LttFacility
* fac
,type_descriptor
* td
,
36 /* generate the facility according to the events belongin to it */
37 void generateFacility(LttFacility
* f
, facility
* fac
,
38 LttChecksum checksum
);
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
);
48 /*****************************************************************************
50 * ltt_facility_open : open facilities
52 * t : the trace containing the facilities
53 * pathname : the path name of the facility
54 ****************************************************************************/
56 void ltt_facility_open(LttTrace
* t
, char * pathname
)
60 char buffer
[BUFFER_SIZE
];
67 in
.error
= error_callback
;
70 in
.fp
= fopen(in
.name
, "r");
71 if(!in
.fp
) in
.error(&in
,"cannot open input file");
74 token
= getToken(&in
);
75 if(in
.type
== ENDFILE
) break;
77 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
80 if(strcmp("facility",token
) == 0) {
81 fac
= g_new(facility
, 1);
83 fac
->description
= NULL
;
84 sequence_init(&(fac
->events
));
85 table_init(&(fac
->named_types
));
86 sequence_init(&(fac
->unnamed_types
));
88 parseFacility(&in
, fac
);
90 //check if any namedType is not defined
91 checkNamedTypesImplemented(&fac
->named_types
);
93 generateChecksum(fac
->name
, &checksum
, &fac
->events
);
95 f
= g_new(LttFacility
,1);
97 generateFacility(f
, fac
, checksum
);
100 g_ptr_array_add(t
->facilities
,f
);
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
);
112 else in
.error(&in
,"facility token was expected");
118 /*****************************************************************************
120 * generateFacility : generate facility, internal function
122 * facility : LttFacilty structure
123 * fac : facility structure
124 * checksum : checksum of the facility
125 ****************************************************************************/
127 void generateFacility(LttFacility
*f
, facility
*fac
,LttChecksum checksum
)
129 char * facilityName
= fac
->name
;
130 sequence
* events
= &fac
->events
;
132 LttEventType
* evType
;
136 f
->name
= g_strdup(facilityName
);
137 f
->event_number
= events
->position
;
138 f
->checksum
= checksum
;
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
;
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
;
151 evType
->name
= g_strdup(((event
*)(events
->array
[i
]))->name
);
152 evType
->description
=g_strdup(((event
*)(events
->array
[i
]))->description
);
154 field
= g_new(LttField
, 1);
155 evType
->root_field
= field
;
156 evType
->facility
= f
;
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
;
172 field
->current_element
= 0;
174 //construct field tree and type graph
175 constructTypeAndFields(f
,((event
*)(events
->array
[i
]))->type
,field
);
177 evType
->root_field
= NULL
;
184 /*****************************************************************************
186 * constructTypeAndFields : construct field tree and type graph,
187 * internal recursion function
189 * fac : facility struct
190 * td : type descriptor
191 * root_field : root field of the event
192 ****************************************************************************/
194 void constructTypeAndFields(LttFacility
* fac
,type_descriptor
* td
,
198 type_descriptor
* tmpTd
;
200 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
201 // fld->field_size = 0;
202 // else fld->field_size = -1;
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
])));
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);
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
;
236 if(fld
->field_type
->element_type
== NULL
){
237 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
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
;
248 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
249 fld
->child
[i
] = g_new(LttField
,1);
251 fld
->child
[i
]->field_pos
= i
;
252 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
255 fld
->child
[i
]->field_type
->element_name
256 = g_strdup(((field
*)(td
->fields
.array
[i
]))->name
);
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
]);
275 /*****************************************************************************
277 * lookup_named_type: search named type in the table
280 * fac : facility struct
281 * td : type descriptor
283 * : either find the named type, or create a new LttType
284 ****************************************************************************/
286 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor
* td
)
288 LttType
* lttType
= NULL
;
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;
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
;
315 lttType
->type_name
= g_strdup(td
->type_name
);
316 fac
->named_types
[i
] = lttType
;
319 lttType
->type_name
= NULL
;
327 /*****************************************************************************
329 * ltt_facility_close : close a facility, decrease its usage count,
330 * if usage count = 0, release the memory
332 * f : facility that will be closed
334 * int : usage count ?? status
335 ****************************************************************************/
337 int ltt_facility_close(LttFacility
*f
)
339 //release the memory it occupied
345 /*****************************************************************************
346 * Functions to release the memory occupied by the facility
347 ****************************************************************************/
349 void freeFacility(LttFacility
* fac
)
352 g_free(fac
->name
); //free facility name
355 for(i
=0;i
<fac
->event_number
;i
++){
356 freeEventtype(fac
->events
[i
]);
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
;
365 g_free(fac
->named_types
);
367 //free the facility itself
371 void freeEventtype(LttEventType
* evType
)
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
);
386 void freeLttNamedType(LttType
* type
)
389 g_free(type
->type_name
);
390 type
->type_name
= NULL
;
394 void freeLttType(LttType
** type
)
397 if(*type
== NULL
) return;
398 if((*type
)->type_name
){
399 return; //this is a named type
401 if((*type
)->element_name
)
402 g_free((*type
)->element_name
);
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
);
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
);
420 void freeLttField(LttField
* fld
)
426 if(fld
->field_type
->type_class
== LTT_ARRAY
||
427 fld
->field_type
->type_class
== LTT_SEQUENCE
){
429 }else if(fld
->field_type
->type_class
== LTT_STRUCT
){
430 size
= fld
->field_type
->element_number
;
435 for(i
=0; i
<size
; i
++){
436 if(fld
->child
[i
])freeLttField(fld
->child
[i
]);
443 /*****************************************************************************
445 * ltt_facility_name : obtain the facility's name
447 * f : the facility that will be closed
449 * char * : the facility's name
450 ****************************************************************************/
452 char *ltt_facility_name(LttFacility
*f
)
457 /*****************************************************************************
459 * ltt_facility_checksum : obtain the facility's checksum
461 * f : the facility that will be closed
463 * LttChecksum : the checksum of the facility
464 ****************************************************************************/
466 LttChecksum
ltt_facility_checksum(LttFacility
*f
)
471 /*****************************************************************************
473 * ltt_facility_base_id : obtain the facility base id
477 * : the base id of the facility
478 ****************************************************************************/
480 unsigned ltt_facility_base_id(LttFacility
*f
)
485 /*****************************************************************************
487 * ltt_facility_eventtype_number: obtain the number of the event types
489 * f : the facility that will be closed
491 * unsigned : the number of the event types
492 ****************************************************************************/
494 unsigned ltt_facility_eventtype_number(LttFacility
*f
)
496 return (unsigned)(f
->event_number
);
499 /*****************************************************************************
501 * ltt_facility_eventtype_get: obtain the event type according to event id
502 * from 0 to event_number - 1
504 * f : the facility that will be closed
506 * LttEventType * : the event type required
507 ****************************************************************************/
509 LttEventType
*ltt_facility_eventtype_get(LttFacility
*f
, unsigned i
)
514 /*****************************************************************************
516 * ltt_facility_eventtype_get_by_name
517 * : obtain the event type according to event name
518 * event name is unique in the facility
520 * f : the facility that will be closed
521 * name : the name of the event
523 * LttEventType * : the event type required
524 ****************************************************************************/
526 LttEventType
*ltt_facility_eventtype_get_by_name(LttFacility
*f
, char *name
)
530 for(i
=0;i
<f
->event_number
;i
++){
532 if(strcmp(ev
->name
, name
) == 0)break;
535 if(i
==f
->event_number
) return NULL
;
This page took 0.040684 seconds and 4 git commands to generate.