ltt library extra careful warnings check
[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_t * 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_t * 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_t, 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_t *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_t*)(events->array[i]))->name);
152 evType->description=g_strdup(((event_t*)(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_t*)(events->array[i]))->type != NULL){
160 field->field_pos = 0;
161 type = lookup_named_type(f,((event_t*)(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_t*)(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 = ((type_fields*)(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(((type_fields*)(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 unsigned 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 unsigned 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 g_free(type->type_name);
389 type->type_name = NULL;
390 freeLttType(&type);
391 }
392
393 void freeLttType(LttType ** type)
394 {
395 unsigned int i;
396 if(*type == NULL) return;
397 if((*type)->type_name){
398 return; //this is a named type
399 }
400 if((*type)->element_name)
401 g_free((*type)->element_name);
402 if((*type)->fmt)
403 g_free((*type)->fmt);
404 if((*type)->enum_strings){
405 for(i=0;i<(*type)->element_number;i++)
406 g_free((*type)->enum_strings[i]);
407 g_free((*type)->enum_strings);
408 }
409
410 if((*type)->element_type){
411 for(i=0;i<(*type)->element_number;i++)
412 freeLttType(&((*type)->element_type[i]));
413 g_free((*type)->element_type);
414 }
415 g_free(*type);
416 *type = NULL;
417 }
418
419 void freeLttField(LttField * fld)
420 {
421 int i;
422 int size = 0;
423
424 if(fld->field_type){
425 if(fld->field_type->type_class == LTT_ARRAY ||
426 fld->field_type->type_class == LTT_SEQUENCE){
427 size = 1;
428 }else if(fld->field_type->type_class == LTT_STRUCT){
429 size = fld->field_type->element_number;
430 }
431 }
432
433 if(fld->child){
434 for(i=0; i<size; i++){
435 if(fld->child[i])freeLttField(fld->child[i]);
436 }
437 g_free(fld->child);
438 }
439 g_free(fld);
440 }
441
442 /*****************************************************************************
443 *Function name
444 * ltt_facility_name : obtain the facility's name
445 *Input params
446 * f : the facility that will be closed
447 *Return value
448 * char * : the facility's name
449 ****************************************************************************/
450
451 char *ltt_facility_name(LttFacility *f)
452 {
453 return f->name;
454 }
455
456 /*****************************************************************************
457 *Function name
458 * ltt_facility_checksum : obtain the facility's checksum
459 *Input params
460 * f : the facility that will be closed
461 *Return value
462 * LttChecksum : the checksum of the facility
463 ****************************************************************************/
464
465 LttChecksum ltt_facility_checksum(LttFacility *f)
466 {
467 return f->checksum;
468 }
469
470 /*****************************************************************************
471 *Function name
472 * ltt_facility_base_id : obtain the facility base id
473 *Input params
474 * f : the facility
475 *Return value
476 * : the base id of the facility
477 ****************************************************************************/
478
479 unsigned ltt_facility_base_id(LttFacility *f)
480 {
481 return f->base_id;
482 }
483
484 /*****************************************************************************
485 *Function name
486 * ltt_facility_eventtype_number: obtain the number of the event types
487 *Input params
488 * f : the facility that will be closed
489 *Return value
490 * unsigned : the number of the event types
491 ****************************************************************************/
492
493 unsigned ltt_facility_eventtype_number(LttFacility *f)
494 {
495 return (f->event_number);
496 }
497
498 /*****************************************************************************
499 *Function name
500 * ltt_facility_eventtype_get: obtain the event type according to event id
501 * from 0 to event_number - 1
502 *Input params
503 * f : the facility that will be closed
504 *Return value
505 * LttEventType * : the event type required
506 ****************************************************************************/
507
508 LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
509 {
510 return f->events[i];
511 }
512
513 /*****************************************************************************
514 *Function name
515 * ltt_facility_eventtype_get_by_name
516 * : obtain the event type according to event name
517 * event name is unique in the facility
518 *Input params
519 * f : the facility that will be closed
520 * name : the name of the event
521 *Return value
522 * LttEventType * : the event type required
523 ****************************************************************************/
524
525 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, char *name)
526 {
527 unsigned int i;
528 LttEventType * ev;
529 for(i=0;i<f->event_number;i++){
530 ev = f->events[i];
531 if(strcmp(ev->name, name) == 0)break;
532 }
533
534 if(i==f->event_number) return NULL;
535 else return ev;
536 }
537
This page took 0.04664 seconds and 4 git commands to generate.