-Wall -Wformat fixes
[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 * 2005 Mathieu Desnoyers
4 *
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;
8 *
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.
13 *
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,
17 * MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <glib.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32
33
34 #include "parser.h"
35 #include <ltt/ltt.h>
36 #include "ltt-private.h"
37 #include <ltt/facility.h>
38
39 #ifndef g_open
40 #define g_open open
41 #endif
42
43 #define g_close close
44
45 /* search for the (named) type in the table, if it does not exist
46 create a new one */
47 LttType * lookup_named_type(LttFacility *fac, type_descriptor_t * td);
48
49 /* construct directed acyclic graph for types, and tree for fields */
50 void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td,
51 LttField * fld);
52
53 /* generate the facility according to the events belongin to it */
54 void generateFacility(LttFacility * f, facility_t * fac,
55 guint32 checksum);
56
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);
63
64
65 /*****************************************************************************
66 *Function name
67 * ltt_facility_open : open facilities
68 *Input params
69 * t : the trace containing the facilities
70 * pathname : the path name of the facility
71 *
72 *returns 0 on success, 1 on error.
73 ****************************************************************************/
74
75 int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname)
76 {
77 int ret = 0;
78 gchar *token;
79 parse_file_t in;
80 facility_t * fac;
81 unsigned long checksum;
82 //GError * error = NULL;
83 gchar buffer[BUFFER_SIZE];
84
85 in.buffer = &(buffer[0]);
86 in.lineno = 0;
87 in.error = error_callback;
88 in.name = pathname;
89
90 //in.fd = g_open(in.name, O_RDONLY, 0);
91 //if(in.fd < 0 ) {
92 in.fp = fopen(in.name, "r");
93 if(in.fp == NULL) {
94 g_warning("cannot open facility description file %s",
95 in.name);
96 ret = 1;
97 goto open_error;
98 }
99
100 //in.channel = g_io_channel_unix_new(in.fd);
101 //in.pos = 0;
102
103 while(1){
104 token = getToken(&in);
105 if(in.type == ENDFILE) break;
106
107 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
108 token = getName(&in);
109
110 if(g_ascii_strcasecmp("facility",token) == 0) {
111 fac = g_new(facility_t, 1);
112 fac->name = NULL;
113 fac->description = NULL;
114 sequence_init(&(fac->events));
115 table_init(&(fac->named_types));
116 sequence_init(&(fac->unnamed_types));
117
118 parseFacility(&in, fac);
119
120 //check if any namedType is not defined
121 checkNamedTypesImplemented(&fac->named_types);
122
123 generateChecksum(fac->name, &checksum, &fac->events);
124
125 generateFacility(f, fac, checksum);
126
127 g_free(fac->name);
128 g_free(fac->description);
129 freeEvents(&fac->events);
130 sequence_dispose(&fac->events);
131 freeNamedType(&fac->named_types);
132 table_dispose(&fac->named_types);
133 freeTypes(&fac->unnamed_types);
134 sequence_dispose(&fac->unnamed_types);
135 g_free(fac);
136 }
137 else {
138 g_warning("facility token was expected in file %s", in.name);
139 ret = 1;
140 goto parse_error;
141 }
142 }
143
144 parse_error:
145 //g_io_channel_shutdown(in.channel, FALSE, &error); /* No flush */
146 //if(error != NULL) {
147 fclose(in.fp);
148 open_error:
149 // g_warning("Can not close file: \n%s\n", error->message);
150 // g_error_free(error);
151 //}
152
153 //g_close(in.fd);
154 return ret;
155 }
156
157
158 /*****************************************************************************
159 *Function name
160 * generateFacility : generate facility, internal function
161 *Input params
162 * facility : LttFacilty structure
163 * fac : facility structure
164 * checksum : checksum of the facility
165 ****************************************************************************/
166
167 void generateFacility(LttFacility *f, facility_t *fac, guint32 checksum)
168 {
169 char * facilityName = fac->name;
170 sequence_t * events = &fac->events;
171 int i;
172 //LttEventType * evType;
173 LttEventType * event_type;
174 LttField * field;
175 LttType * type;
176
177 g_assert(f->name == g_quark_from_string(facilityName));
178 g_assert(f->checksum == checksum);
179
180 //f->event_number = events->position;
181
182 //initialize inner structures
183 f->events = g_array_sized_new (FALSE, TRUE, sizeof(LttEventType),
184 events->position);
185 //f->events = g_new(LttEventType*,f->event_number);
186 f->events = g_array_set_size(f->events, events->position);
187
188 g_datalist_init(&f->events_by_name);
189 g_datalist_init(&f->named_types);
190
191 //f->named_types_number = fac->named_types.keys.position;
192 //f->named_types = g_array_sized_new (FALSE, TRUE, sizeof(LttType),
193 // fac->named_types.keys.position);
194 //f->named_types = g_new(LttType*, fac->named_types.keys.position);
195 //f->named_types = g_array_set_size(f->named_types,
196 // fac->named_types.keys.position);
197
198 //for each event, construct field tree and type graph
199 for(i=0;i<events->position;i++){
200 event_type = &g_array_index(f->events, LttEventType, i);
201 //evType = g_new(LttEventType,1);
202 //f->events[i] = evType;
203
204 event_type->name =
205 g_quark_from_string(((event_t*)(events->array[i]))->name);
206
207 g_datalist_id_set_data(&f->events_by_name, event_type->name,
208 event_type);
209
210 event_type->description =
211 g_strdup(((event_t*)(events->array[i]))->description);
212
213 field = g_new(LttField, 1);
214 event_type->root_field = field;
215 event_type->facility = f;
216 event_type->index = i;
217
218 if(((event_t*)(events->array[i]))->type != NULL){
219 // field->field_pos = 0;
220 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
221 field->field_type = type;
222 field->offset_root = 0;
223 field->fixed_root = FIELD_UNKNOWN;
224 field->offset_parent = 0;
225 field->fixed_parent = FIELD_UNKNOWN;
226 // field->base_address = NULL;
227 field->field_size = 0;
228 field->fixed_size = FIELD_UNKNOWN;
229 field->parent = NULL;
230 field->child = NULL;
231 field->current_element = 0;
232
233 //construct field tree and type graph
234 construct_types_and_fields(f,((event_t*)(events->array[i]))->type,field);
235 }else{
236 event_type->root_field = NULL;
237 g_free(field);
238 }
239 }
240 }
241
242
243 /*****************************************************************************
244 *Function name
245 * construct_types_and_fields : construct field tree and type graph,
246 * internal recursion function
247 *Input params
248 * fac : facility struct
249 * td : type descriptor
250 * root_field : root field of the event
251 ****************************************************************************/
252
253
254 void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td,
255 LttField * fld)
256 {
257 int i;
258 type_descriptor_t * tmpTd;
259
260 switch(td->type) {
261 case INT:
262 case UINT:
263 case FLOAT:
264 fld->field_type->size = td->size;
265 break;
266 case POINTER:
267 case LONG:
268 case ULONG:
269 case SIZE_T:
270 case SSIZE_T:
271 case OFF_T:
272 fld->field_type->size = 0;
273 break;
274 case STRING:
275 fld->field_type->size = 0;
276 break;
277 case ENUM:
278 fld->field_type->element_number = td->labels.position;
279 fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
280 for(i=0;i<td->labels.position;i++){
281 fld->field_type->enum_strings[i]
282 = g_quark_from_string(((char*)(td->labels.array[i])));
283 }
284 fld->field_type->size = td->size;
285 break;
286
287 case ARRAY:
288 fld->field_type->element_number = (unsigned)td->size;
289 case SEQUENCE:
290 fld->field_type->element_type = g_new(LttType*,1);
291 tmpTd = td->nested_type;
292 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
293 fld->child = g_new(LttField*, 1);
294 fld->child[0] = g_new(LttField, 1);
295
296 fld->child[0]->field_type = fld->field_type->element_type[0];
297 fld->child[0]->offset_root = 0;
298 fld->child[0]->fixed_root = FIELD_UNKNOWN;
299 fld->child[0]->offset_parent = 0;
300 fld->child[0]->fixed_parent = FIELD_UNKNOWN;
301 fld->child[0]->field_size = 0;
302 fld->child[0]->fixed_size = FIELD_UNKNOWN;
303 fld->child[0]->parent = fld;
304 fld->child[0]->child = NULL;
305 fld->child[0]->current_element = 0;
306 construct_types_and_fields(fac, tmpTd, fld->child[0]);
307 break;
308
309 case STRUCT:
310 case UNION:
311 fld->field_type->element_number = td->fields.position;
312
313 g_assert(fld->field_type->element_type == NULL);
314 fld->field_type->element_type = g_new(LttType*, td->fields.position);
315
316 fld->child = g_new(LttField*, td->fields.position);
317 for(i=0;i<td->fields.position;i++){
318 tmpTd = ((field_t*)(td->fields.array[i]))->type;
319
320 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
321 fld->child[i] = g_new(LttField,1);
322
323 // fld->child[i]->field_pos = i;
324 fld->child[i]->field_type = fld->field_type->element_type[i];
325
326 fld->child[i]->field_type->element_name
327 = g_quark_from_string(((field_t*)(td->fields.array[i]))->name);
328
329 fld->child[i]->offset_root = 0;
330 fld->child[i]->fixed_root = FIELD_UNKNOWN;
331 fld->child[i]->offset_parent = 0;
332 fld->child[i]->fixed_parent = FIELD_UNKNOWN;
333 fld->child[i]->field_size = 0;
334 fld->child[i]->fixed_size = FIELD_UNKNOWN;
335 fld->child[i]->parent = fld;
336 fld->child[i]->child = NULL;
337 fld->child[i]->current_element = 0;
338 construct_types_and_fields(fac, tmpTd, fld->child[i]);
339 }
340 break;
341
342 default:
343 g_error("construct_types_and_fields : unknown type");
344 }
345
346
347 }
348
349
350
351 #if 0
352 void construct_types_and_fields(LttFacility * fac, type_descriptor * td,
353 LttField * fld)
354 {
355 int i, flag;
356 type_descriptor * tmpTd;
357
358 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
359 // fld->field_size = 0;
360 // else fld->field_size = -1;
361
362 if(td->type == LTT_ENUM){
363 fld->field_type->element_number = td->labels.position;
364 fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
365 for(i=0;i<td->labels.position;i++){
366 fld->field_type->enum_strings[i]
367 = g_quark_from_string(((char*)(td->labels.array[i])));
368 }
369 }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
370 if(td->type == LTT_ARRAY)
371 fld->field_type->element_number = (unsigned)td->size;
372 fld->field_type->element_type = g_new(LttType*,1);
373 tmpTd = td->nested_type;
374 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
375 fld->child = g_new(LttField*, 1);
376 fld->child[0] = g_new(LttField, 1);
377
378 // fld->child[0]->field_pos = 0;
379 fld->child[0]->field_type = fld->field_type->element_type[0];
380 fld->child[0]->offset_root = fld->offset_root;
381 fld->child[0]->fixed_root = fld->fixed_root;
382 fld->child[0]->offset_parent = 0;
383 fld->child[0]->fixed_parent = 1;
384 // fld->child[0]->base_address = NULL;
385 fld->child[0]->field_size = 0;
386 fld->child[0]->field_fixed = -1;
387 fld->child[0]->parent = fld;
388 fld->child[0]->child = NULL;
389 fld->child[0]->current_element = 0;
390 construct_types_and_fields(fac, tmpTd, fld->child[0]);
391 }else if(td->type == LTT_STRUCT){
392 fld->field_type->element_number = td->fields.position;
393
394 if(fld->field_type->element_type == NULL){
395 fld->field_type->element_type = g_new(LttType*, td->fields.position);
396 flag = 1;
397 }else{
398 flag = 0;
399 }
400
401 fld->child = g_new(LttField*, td->fields.position);
402 for(i=0;i<td->fields.position;i++){
403 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
404
405 if(flag)
406 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
407 fld->child[i] = g_new(LttField,1);
408
409 fld->child[i]->field_pos = i;
410 fld->child[i]->field_type = fld->field_type->element_type[i];
411
412 if(flag){
413 fld->child[i]->field_type->element_name
414 = g_quark_from_string(((type_fields*)(td->fields.array[i]))->name);
415 }
416
417 fld->child[i]->offset_root = -1;
418 fld->child[i]->fixed_root = -1;
419 fld->child[i]->offset_parent = -1;
420 fld->child[i]->fixed_parent = -1;
421 // fld->child[i]->base_address = NULL;
422 fld->child[i]->field_size = 0;
423 fld->child[i]->field_fixed = -1;
424 fld->child[i]->parent = fld;
425 fld->child[i]->child = NULL;
426 fld->child[i]->current_element = 0;
427 construct_types_and_fields(fac, tmpTd, fld->child[i]);
428 }
429 }
430 }
431 #endif //0
432
433 /*****************************************************************************
434 *Function name
435 * lookup_named_type: search named type in the table
436 * internal function
437 *Input params
438 * fac : facility struct
439 * td : type descriptor
440 *Return value
441 * : either find the named type, or create a new LttType
442 ****************************************************************************/
443
444 LttType * lookup_named_type(LttFacility *fac, type_descriptor_t * td)
445 {
446 LttType *type = NULL;
447 GQuark name = 0;
448
449 if(td->type_name != NULL) {
450 /* Named type */
451 name = g_quark_from_string(td->type_name);
452
453 type = g_datalist_id_get_data(&fac->named_types, name);
454 }
455
456 if(type == NULL){
457 /* Create the type */
458 type = g_new(LttType,1);
459 type->type_name = name;
460 type->type_class = td->type;
461 if(td->fmt) type->fmt = g_strdup(td->fmt);
462 else type->fmt = NULL;
463 type->size = td->size;
464 type->enum_strings = NULL;
465 type->element_type = NULL;
466 type->element_number = 0;
467
468 if(td->type_name != NULL)
469 g_datalist_id_set_data_full(&fac->named_types, name,
470 type, (GDestroyNotify)freeLttNamedType);
471 }
472 return type;
473 }
474
475
476 /*****************************************************************************
477 *Function name
478 * ltt_facility_close : close a facility, decrease its usage count,
479 * if usage count = 0, release the memory
480 *Input params
481 * f : facility that will be closed
482 ****************************************************************************/
483
484 void ltt_facility_close(LttFacility *f)
485 {
486 //release the memory it occupied
487 freeFacility(f);
488 }
489
490 /*****************************************************************************
491 * Functions to release the memory occupied by the facility
492 ****************************************************************************/
493
494 void freeFacility(LttFacility * fac)
495 {
496 guint i;
497 LttEventType *et;
498
499 for(i=0; i<fac->events->len; i++) {
500 et = &g_array_index (fac->events, LttEventType, i);
501 freeEventtype(et);
502 }
503 g_array_free(fac->events, TRUE);
504
505 g_datalist_clear(&fac->named_types);
506
507 }
508
509 void freeEventtype(LttEventType * evType)
510 {
511 LttType * root_type;
512 if(evType->description)
513 g_free(evType->description);
514 if(evType->root_field){
515 root_type = evType->root_field->field_type;
516 freeLttField(evType->root_field);
517 freeLttType(&root_type);
518 }
519 }
520
521 void freeLttNamedType(LttType * type)
522 {
523 freeLttType(&type);
524 }
525
526 void freeLttType(LttType ** type)
527 {
528 unsigned int i;
529 if(*type == NULL) return;
530 if((*type)->type_name != 0) return; //this is a named type.
531 //if((*type)->type_name){
532 // return; //this is a named type
533 //}
534 if((*type)->fmt)
535 g_free((*type)->fmt);
536 if((*type)->enum_strings){
537 g_free((*type)->enum_strings);
538 }
539
540 if((*type)->element_type){
541 for(i=0;i<(*type)->element_number;i++)
542 freeLttType(&((*type)->element_type[i]));
543 g_free((*type)->element_type);
544 }
545 g_free(*type);
546 *type = NULL;
547 }
548
549 void freeLttField(LttField * fld)
550 {
551 int i;
552 int size = 0;
553
554 if(fld->field_type){
555 if(fld->field_type->type_class == LTT_ARRAY ||
556 fld->field_type->type_class == LTT_SEQUENCE){
557 size = 1;
558 }else if(fld->field_type->type_class == LTT_STRUCT){
559 size = fld->field_type->element_number;
560 }
561 }
562
563 if(fld->child){
564 for(i=0; i<size; i++){
565 if(fld->child[i])freeLttField(fld->child[i]);
566 }
567 g_free(fld->child);
568 }
569 g_free(fld);
570 }
571
572 /*****************************************************************************
573 *Function name
574 * ltt_facility_name : obtain the facility's name
575 *Input params
576 * f : the facility
577 *Return value
578 * GQuark : the facility's name
579 ****************************************************************************/
580
581 GQuark ltt_facility_name(LttFacility *f)
582 {
583 return f->name;
584 }
585
586 /*****************************************************************************
587 *Function name
588 * ltt_facility_checksum : obtain the facility's checksum
589 *Input params
590 * f : the facility
591 *Return value
592 * : the checksum of the facility
593 ****************************************************************************/
594
595 guint32 ltt_facility_checksum(LttFacility *f)
596 {
597 return f->checksum;
598 }
599
600 /*****************************************************************************
601 *Function name
602 * ltt_facility_base_id : obtain the facility base id
603 *Input params
604 * f : the facility
605 *Return value
606 * : the base id of the facility
607 ****************************************************************************/
608
609 guint ltt_facility_id(LttFacility *f)
610 {
611 return f->id;
612 }
613
614 /*****************************************************************************
615 *Function name
616 * ltt_facility_eventtype_number: obtain the number of the event types
617 *Input params
618 * f : the facility that will be closed
619 *Return value
620 * : the number of the event types
621 ****************************************************************************/
622
623 guint8 ltt_facility_eventtype_number(LttFacility *f)
624 {
625 return (f->events->len);
626 }
627
628 /*****************************************************************************
629 *Function name
630 * ltt_facility_eventtype_get: obtain the event type according to event id
631 * from 0 to event_number - 1
632 *Input params
633 * f : the facility that will be closed
634 *Return value
635 * LttEventType * : the event type required
636 ****************************************************************************/
637
638 LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i)
639 {
640 if(!f->exists) return NULL;
641
642 g_assert(i < f->events->len);
643 return &g_array_index(f->events, LttEventType, i);
644 }
645
646 /*****************************************************************************
647 *Function name
648 * ltt_facility_eventtype_get_by_name
649 * : obtain the event type according to event name
650 * event name is unique in the facility
651 *Input params
652 * f : the facility
653 * name : the name of the event
654 *Return value
655 * LttEventType * : the event type required
656 ****************************************************************************/
657
658 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name)
659 {
660 LttEventType *et = g_datalist_id_get_data(&f->events_by_name, name);
661 return et;
662 }
663
This page took 0.05173 seconds and 4 git commands to generate.