update for facility mismatch
[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 library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License Version 2.1 as published by the Free Software Foundation.
8 *
9 * This library 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, 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_fields(LttFacility *fac,
51 LttField *field,
52 field_t *fld);
53
54 /* generate the facility according to the events belongin to it */
55 void generateFacility(LttFacility * f, facility_t * fac,
56 guint32 checksum);
57
58 /* functions to release the memory occupied by a facility */
59 void freeFacility(LttFacility * facility);
60 void freeEventtype(LttEventType * evType);
61 void freeLttType(LttType * type);
62 void freeLttField(LttField * fld);
63 void freeLttNamedType(LttType * type);
64
65
66 /*****************************************************************************
67 *Function name
68 * ltt_facility_open : open facilities
69 *Input params
70 * t : the trace containing the facilities
71 * pathname : the path name of the facility
72 *
73 * Open the facility corresponding to the right checksum.
74 *
75 *returns 0 on success, 1 on error.
76 ****************************************************************************/
77
78 int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname)
79 {
80 int ret = 0;
81 gchar *token;
82 parse_file_t in;
83 facility_t * fac;
84 unsigned int checksum;
85 gchar buffer[BUFFER_SIZE];
86 gboolean generated = FALSE;
87
88 in.buffer = &(buffer[0]);
89 in.lineno = 0;
90 in.error = error_callback;
91 in.name = pathname;
92 in.unget = 0;
93
94 in.fp = fopen(in.name, "r");
95 if(in.fp == NULL) {
96 g_warning("cannot open facility description file %s",
97 in.name);
98 ret = 1;
99 goto open_error;
100 }
101
102 while(1){
103 token = getToken(&in);
104 if(in.type == ENDFILE) break;
105
106 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
107 token = getName(&in);
108 if(g_ascii_strcasecmp(token, "?")) in.error(&in,"not a facility file");
109 token = getName(&in);
110 if(g_ascii_strcasecmp(token, "xml")) in.error(&in,"not a facility file");
111 token = getName(&in);
112 if(g_ascii_strcasecmp(token, "version")) in.error(&in,"not a facility file");
113 token = getName(&in);
114 if(g_ascii_strcasecmp(token, "=")) in.error(&in,"not a facility file");
115 token = getQuotedString(&in);
116 if(g_ascii_strcasecmp(token, "1.0")) in.error(&in,"not a facility file");
117 token = getName(&in);
118 if(g_ascii_strcasecmp(token, "?")) in.error(&in,"not a facility file");
119 token = getToken(&in);
120 if(g_ascii_strcasecmp(token, ">")) in.error(&in,"not a facility file");
121
122 token = getToken(&in);
123
124 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
125 token = getName(&in);
126
127 if(g_ascii_strcasecmp("facility",token) == 0) {
128 fac = g_new(facility_t, 1);
129 fac->name = NULL;
130 fac->description = NULL;
131 sequence_init(&(fac->events));
132 table_init(&(fac->named_types));
133 sequence_init(&(fac->unnamed_types));
134
135 parseFacility(&in, fac);
136
137 //check if any namedType is not defined
138 checkNamedTypesImplemented(&fac->named_types);
139
140 generateChecksum(fac->name, &checksum, &fac->events);
141 // FIXME if(checksum == f->checksum) {
142 generateFacility(f, fac, checksum);
143 generated = TRUE;
144 //}
145 if (checksum != f->checksum)
146 g_warning("Facility checksum mismatch for facility %s : kernel 0x%X vs "
147 "XML 0x%X\n", fac->name, f->checksum, checksum);
148
149 g_free(fac->name);
150 free(fac->capname);
151 g_free(fac->description);
152 freeEvents(&fac->events);
153 sequence_dispose(&fac->events);
154 freeNamedType(&fac->named_types);
155 table_dispose(&fac->named_types);
156 freeTypes(&fac->unnamed_types);
157 sequence_dispose(&fac->unnamed_types);
158 g_free(fac);
159 if(generated) break; /* use the first good match */
160 }
161 else {
162 g_warning("facility token was expected in file %s", in.name);
163 ret = 1;
164 goto parse_error;
165 }
166 }
167
168 parse_error:
169 fclose(in.fp);
170 open_error:
171
172 if(!generated) {
173 g_warning("Cannot find facility %s, checksum 0x%X",
174 g_quark_to_string(f->name), f->checksum);
175 ret = 1;
176 }
177
178 return ret;
179 }
180
181
182 /*****************************************************************************
183 *Function name
184 * generateFacility : generate facility, internal function
185 *Input params
186 * facility : LttFacilty structure
187 * fac : facility structure
188 * checksum : checksum of the facility
189 ****************************************************************************/
190
191 void generateFacility(LttFacility *f, facility_t *fac, guint32 checksum)
192 {
193 char * facilityName = fac->name;
194 sequence_t * events = &fac->events;
195 unsigned int i, j;
196 LttType * type;
197 table_t *named_types = &fac->named_types;
198
199 g_assert(f->name == g_quark_from_string(facilityName));
200 //g_assert(f->checksum == checksum);
201
202 //f->event_number = events->position;
203
204 //initialize inner structures
205 f->events = g_array_sized_new (FALSE, TRUE, sizeof(LttEventType),
206 events->position);
207 //f->events = g_new(LttEventType*,f->event_number);
208 f->events = g_array_set_size(f->events, events->position);
209
210 g_datalist_init(&f->events_by_name);
211 // g_datalist_init(&f->named_types);
212 #if 0
213 /* The first day, he created the named types */
214
215 for(i=0; i<named_types->keys.position; i++) {
216 GQuark name = g_quark_from_string((char*)named_types->keys.array[i]);
217 type_descriptor_t *td = (type_descriptor_t*)named_types->values.array[i];
218
219 /* Create the type */
220 type = g_new(LttType,1);
221 type->type_name = name;
222 type->type_class = td->type;
223 if(td->fmt) type->fmt = g_strdup(td->fmt);
224 else type->fmt = NULL;
225 type->size = td->size;
226 type->enum_strings = NULL;
227 type->element_type = NULL;
228 type->element_number = 0;
229
230 construct_types_and_fields(type, td, NULL, NULL, ...);
231
232 g_datalist_id_set_data_full(&fac->named_types, name,
233 type, (GDestroyNotify)freeLttNamedType);
234
235 }
236 #endif //0
237 /* The second day, he created the event fields and types */
238 //for each event, construct field and type acyclic graph
239 for(i=0;i<events->position;i++){
240 event_t *parser_event = (event_t*)events->array[i];
241 LttEventType *event_type = &g_array_index(f->events, LttEventType, i);
242
243 event_type->name =
244 g_quark_from_string(parser_event->name);
245
246 g_datalist_id_set_data(&f->events_by_name, event_type->name,
247 event_type);
248
249 event_type->description =
250 g_strdup(parser_event->description);
251
252 event_type->index = i;
253 event_type->facility = f;
254
255 event_type->has_compact_data = parser_event->compact_data;
256
257 event_type->fields = g_array_sized_new(FALSE, TRUE,
258 sizeof(LttField), parser_event->fields.position);
259 event_type->fields =
260 g_array_set_size(event_type->fields, parser_event->fields.position);
261 g_datalist_init(&event_type->fields_by_name);
262
263 for(j=0; j<parser_event->fields.position; j++) {
264 LttField *field = &g_array_index(event_type->fields, LttField, j);
265 field_t *parser_field = (field_t*)parser_event->fields.array[j];
266
267 construct_fields(f, field, parser_field);
268 g_datalist_id_set_data(&event_type->fields_by_name,
269 field->name,
270 field);
271 }
272 }
273
274 /* What about 2 days weeks ? */
275 }
276
277
278 /*****************************************************************************
279 *Function name
280 * construct_types_and_fields : construct field tree and type graph,
281 * internal recursion function
282 *Input params
283 * fac : facility struct
284 * field : destination lttv field
285 * fld : source parser field
286 ****************************************************************************/
287
288 //DONE
289 //make the change for arrays and sequences
290 //no more root field. -> change this for an array of fields.
291 // Compute the field size here.
292 // Flag fields as "VARIABLE OFFSET" or "FIXED OFFSET" : as soon as
293 // a field with a variable size is found, all the following fields must
294 // be flagged with "VARIABLE OFFSET", this will be done by the offset
295 // precomputation.
296
297
298 void construct_fields(LttFacility *fac,
299 LttField *field,
300 field_t *fld)
301 {
302 guint len;
303 type_descriptor_t *td;
304 LttType *type;
305
306 if(fld->name)
307 field->name = g_quark_from_string(fld->name);
308 else
309 fld->name = 0;
310
311 if(fld->description) {
312 len = strlen(fld->description);
313 field->description = g_new(gchar, len+1);
314 strcpy(field->description, fld->description);
315 }
316 field->dynamic_offsets = NULL;
317 type = &field->field_type;
318 td = fld->type;
319
320 type->enum_map = NULL;
321 type->fields = NULL;
322 type->fields_by_name = NULL;
323 type->network = td->network;
324
325 switch(td->type) {
326 case INT_FIXED:
327 type->type_class = LTT_INT_FIXED;
328 type->size = td->size;
329 break;
330 case UINT_FIXED:
331 type->type_class = LTT_UINT_FIXED;
332 type->size = td->size;
333 break;
334 case POINTER:
335 type->type_class = LTT_POINTER;
336 type->size = fac->pointer_size;
337 break;
338 case CHAR:
339 type->type_class = LTT_CHAR;
340 type->size = td->size;
341 break;
342 case UCHAR:
343 type->type_class = LTT_UCHAR;
344 type->size = td->size;
345 g_assert(type->size != 0);
346 break;
347 case SHORT:
348 type->type_class = LTT_SHORT;
349 type->size = td->size;
350 break;
351 case USHORT:
352 type->type_class = LTT_USHORT;
353 type->size = td->size;
354 break;
355 case INT:
356 type->type_class = LTT_INT;
357 type->size = fac->int_size;
358 break;
359 case UINT:
360 type->type_class = LTT_UINT;
361 type->size = fac->int_size;
362 g_assert(type->size != 0);
363 break;
364 case LONG:
365 type->type_class = LTT_LONG;
366 type->size = fac->long_size;
367 break;
368 case ULONG:
369 type->type_class = LTT_ULONG;
370 type->size = fac->long_size;
371 break;
372 case SIZE_T:
373 type->type_class = LTT_SIZE_T;
374 type->size = fac->size_t_size;
375 break;
376 case SSIZE_T:
377 type->type_class = LTT_SSIZE_T;
378 type->size = fac->size_t_size;
379 break;
380 case OFF_T:
381 type->type_class = LTT_OFF_T;
382 type->size = fac->size_t_size;
383 break;
384 case FLOAT:
385 type->type_class = LTT_FLOAT;
386 type->size = td->size;
387 break;
388 case STRING:
389 type->type_class = LTT_STRING;
390 type->size = 0;
391 break;
392 case ENUM:
393 type->type_class = LTT_ENUM;
394 type->size = fac->int_size;
395 {
396 guint i;
397 type->enum_map = g_hash_table_new(g_direct_hash, g_direct_equal);
398 for(i=0; i<td->labels.position; i++) {
399 GQuark value = g_quark_from_string((char*)td->labels.array[i]);
400 gint key = *(int*)td->labels_values.array[i];
401 g_hash_table_insert(type->enum_map, (gpointer)key, (gpointer)value);
402 }
403 }
404 g_assert(type->size != 0);
405 break;
406 case ARRAY:
407 type->type_class = LTT_ARRAY;
408 type->size = td->size;
409 type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
410 td->fields.position);
411 type->fields = g_array_set_size(type->fields, td->fields.position);
412 {
413 guint i;
414
415 for(i=0; i<td->fields.position; i++) {
416 field_t *schild = (field_t*)td->fields.array[i];
417 LttField *dchild = &g_array_index(type->fields, LttField, i);
418
419 construct_fields(fac, dchild, schild);
420 }
421 }
422 break;
423 case SEQUENCE:
424 type->type_class = LTT_SEQUENCE;
425 type->size = 0;
426 type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
427 td->fields.position);
428 type->fields = g_array_set_size(type->fields, td->fields.position);
429 {
430 guint i;
431
432 for(i=0; i<td->fields.position; i++) {
433 field_t *schild = (field_t*)td->fields.array[i];
434 LttField *dchild = &g_array_index(type->fields, LttField, i);
435
436 construct_fields(fac, dchild, schild);
437 }
438 }
439 break;
440 case STRUCT:
441 type->type_class = LTT_STRUCT;
442 type->size = 0; // Size not calculated by the parser.
443 type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
444 td->fields.position);
445 type->fields = g_array_set_size(type->fields, td->fields.position);
446 g_datalist_init(&type->fields_by_name);
447 {
448 guint i;
449
450 for(i=0; i<td->fields.position; i++) {
451 field_t *schild = (field_t*)td->fields.array[i];
452 LttField *dchild = &g_array_index(type->fields, LttField, i);
453
454 construct_fields(fac, dchild, schild);
455 g_datalist_id_set_data(&type->fields_by_name,
456 dchild->name,
457 dchild);
458 }
459 }
460 break;
461 case UNION:
462 type->type_class = LTT_UNION;
463 type->size = 0; // Size not calculated by the parser.
464 type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
465 td->fields.position);
466 type->fields = g_array_set_size(type->fields, td->fields.position);
467 g_datalist_init(&type->fields_by_name);
468 {
469 guint i;
470
471 for(i=0; i<td->fields.position; i++) {
472 field_t *schild = (field_t*)td->fields.array[i];
473 LttField *dchild = &g_array_index(type->fields, LttField, i);
474
475 construct_fields(fac, dchild, schild);
476 g_datalist_id_set_data(&type->fields_by_name,
477 dchild->name,
478 dchild);
479 }
480 }
481 break;
482 case NONE:
483 default:
484 g_error("construct_fields : unknown type");
485 }
486
487 field->field_size = type->size;
488
489 /* Put the fields as "variable" offset to root first. Then,
490 * the offset precomputation will only have to set the FIELD_FIXED until
491 * it reaches the first variable length field, then stop.
492 */
493 field->fixed_root = FIELD_VARIABLE;
494
495 if(td->fmt) {
496 len = strlen(td->fmt);
497 type->fmt = g_new(gchar, len+1);
498 strcpy(type->fmt, td->fmt);
499 }
500 }
501
502
503
504 #if 0
505 void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td,
506 LttField * fld)
507 {
508 int i;
509 type_descriptor_t * tmpTd;
510
511 switch(td->type) {
512 case INT:
513 case UINT:
514 case FLOAT:
515 fld->field_type->size = td->size;
516 break;
517 case POINTER:
518 case LONG:
519 case ULONG:
520 case SIZE_T:
521 case SSIZE_T:
522 case OFF_T:
523 fld->field_type->size = 0;
524 break;
525 case STRING:
526 fld->field_type->size = 0;
527 break;
528 case ENUM:
529 fld->field_type->element_number = td->labels.position;
530 fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
531 for(i=0;i<td->labels.position;i++){
532 fld->field_type->enum_strings[i]
533 = g_quark_from_string(((char*)(td->labels.array[i])));
534 }
535 fld->field_type->size = td->size;
536 break;
537
538 case ARRAY:
539 fld->field_type->element_number = (unsigned)td->size;
540 case SEQUENCE:
541 fld->field_type->element_type = g_new(LttType*,1);
542 tmpTd = td->nested_type;
543 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
544 fld->child = g_new(LttField*, 1);
545 fld->child[0] = g_new(LttField, 1);
546
547 fld->child[0]->field_type = fld->field_type->element_type[0];
548 fld->child[0]->offset_root = 0;
549 fld->child[0]->fixed_root = FIELD_UNKNOWN;
550 fld->child[0]->offset_parent = 0;
551 fld->child[0]->fixed_parent = FIELD_UNKNOWN;
552 fld->child[0]->field_size = 0;
553 fld->child[0]->fixed_size = FIELD_UNKNOWN;
554 fld->child[0]->parent = fld;
555 fld->child[0]->child = NULL;
556 fld->child[0]->current_element = 0;
557 construct_types_and_fields(fac, tmpTd, fld->child[0]);
558 break;
559
560 case STRUCT:
561 case UNION:
562 fld->field_type->element_number = td->fields.position;
563
564 g_assert(fld->field_type->element_type == NULL);
565 fld->field_type->element_type = g_new(LttType*, td->fields.position);
566
567 fld->child = g_new(LttField*, td->fields.position);
568 for(i=0;i<td->fields.position;i++){
569 tmpTd = ((field_t*)(td->fields.array[i]))->type;
570
571 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
572 fld->child[i] = g_new(LttField,1);
573
574 // fld->child[i]->field_pos = i;
575 fld->child[i]->field_type = fld->field_type->element_type[i];
576
577 fld->child[i]->field_type->element_name
578 = g_quark_from_string(((field_t*)(td->fields.array[i]))->name);
579
580 fld->child[i]->offset_root = 0;
581 fld->child[i]->fixed_root = FIELD_UNKNOWN;
582 fld->child[i]->offset_parent = 0;
583 fld->child[i]->fixed_parent = FIELD_UNKNOWN;
584 fld->child[i]->field_size = 0;
585 fld->child[i]->fixed_size = FIELD_UNKNOWN;
586 fld->child[i]->parent = fld;
587 fld->child[i]->child = NULL;
588 fld->child[i]->current_element = 0;
589 construct_types_and_fields(fac, tmpTd, fld->child[i]);
590 }
591 break;
592
593 default:
594 g_error("construct_types_and_fields : unknown type");
595 }
596
597
598 }
599
600 #endif //0
601
602 #if 0
603 void construct_types_and_fields(LttFacility * fac, type_descriptor * td,
604 LttField * fld)
605 {
606 int i, flag;
607 type_descriptor * tmpTd;
608
609 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
610 // fld->field_size = 0;
611 // else fld->field_size = -1;
612
613 if(td->type == LTT_ENUM){
614 fld->field_type->element_number = td->labels.position;
615 fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
616 for(i=0;i<td->labels.position;i++){
617 fld->field_type->enum_strings[i]
618 = g_quark_from_string(((char*)(td->labels.array[i])));
619 }
620 }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
621 if(td->type == LTT_ARRAY)
622 fld->field_type->element_number = (unsigned)td->size;
623 fld->field_type->element_type = g_new(LttType*,1);
624 tmpTd = td->nested_type;
625 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
626 fld->child = g_new(LttField*, 1);
627 fld->child[0] = g_new(LttField, 1);
628
629 // fld->child[0]->field_pos = 0;
630 fld->child[0]->field_type = fld->field_type->element_type[0];
631 fld->child[0]->offset_root = fld->offset_root;
632 fld->child[0]->fixed_root = fld->fixed_root;
633 fld->child[0]->offset_parent = 0;
634 fld->child[0]->fixed_parent = 1;
635 // fld->child[0]->base_address = NULL;
636 fld->child[0]->field_size = 0;
637 fld->child[0]->field_fixed = -1;
638 fld->child[0]->parent = fld;
639 fld->child[0]->child = NULL;
640 fld->child[0]->current_element = 0;
641 construct_types_and_fields(fac, tmpTd, fld->child[0]);
642 }else if(td->type == LTT_STRUCT){
643 fld->field_type->element_number = td->fields.position;
644
645 if(fld->field_type->element_type == NULL){
646 fld->field_type->element_type = g_new(LttType*, td->fields.position);
647 flag = 1;
648 }else{
649 flag = 0;
650 }
651
652 fld->child = g_new(LttField*, td->fields.position);
653 for(i=0;i<td->fields.position;i++){
654 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
655
656 if(flag)
657 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
658 fld->child[i] = g_new(LttField,1);
659
660 fld->child[i]->field_pos = i;
661 fld->child[i]->field_type = fld->field_type->element_type[i];
662
663 if(flag){
664 fld->child[i]->field_type->element_name
665 = g_quark_from_string(((type_fields*)(td->fields.array[i]))->name);
666 }
667
668 fld->child[i]->offset_root = -1;
669 fld->child[i]->fixed_root = -1;
670 fld->child[i]->offset_parent = -1;
671 fld->child[i]->fixed_parent = -1;
672 // fld->child[i]->base_address = NULL;
673 fld->child[i]->field_size = 0;
674 fld->child[i]->field_fixed = -1;
675 fld->child[i]->parent = fld;
676 fld->child[i]->child = NULL;
677 fld->child[i]->current_element = 0;
678 construct_types_and_fields(fac, tmpTd, fld->child[i]);
679 }
680 }
681 }
682 #endif //0
683
684 #if 0
685 /*****************************************************************************
686 *Function name
687 * lookup_named_type: search named type in the table
688 * internal function
689 *Input params
690 * fac : facility struct
691 * name : type name
692 *Return value
693 * : either find the named type, or create a new LttType
694 ****************************************************************************/
695
696 LttType * lookup_named_type(LttFacility *fac, GQuark type_name)
697 {
698 LttType *type = NULL;
699
700 /* Named type */
701 type = g_datalist_id_get_data(&fac->named_types, name);
702
703 g_assert(type != NULL);
704 #if 0
705 if(type == NULL){
706 /* Create the type */
707 type = g_new(LttType,1);
708 type->type_name = name;
709 type->type_class = td->type;
710 if(td->fmt) type->fmt = g_strdup(td->fmt);
711 else type->fmt = NULL;
712 type->size = td->size;
713 type->enum_strings = NULL;
714 type->element_type = NULL;
715 type->element_number = 0;
716
717 if(td->type_name != NULL)
718 g_datalist_id_set_data_full(&fac->named_types, name,
719 type, (GDestroyNotify)freeLttNamedType);
720 }
721 #endif //0
722 return type;
723 }
724 #endif //0
725
726 /*****************************************************************************
727 *Function name
728 * ltt_facility_close : close a facility, decrease its usage count,
729 * if usage count = 0, release the memory
730 *Input params
731 * f : facility that will be closed
732 ****************************************************************************/
733
734 void ltt_facility_close(LttFacility *f)
735 {
736 //release the memory it occupied
737 freeFacility(f);
738 }
739
740 /*****************************************************************************
741 * Functions to release the memory occupied by the facility
742 ****************************************************************************/
743
744 void freeFacility(LttFacility * fac)
745 {
746 guint i;
747 LttEventType *et;
748
749 for(i=0; i<fac->events->len; i++) {
750 et = &g_array_index (fac->events, LttEventType, i);
751 freeEventtype(et);
752 }
753 g_array_free(fac->events, TRUE);
754
755 g_datalist_clear(&fac->events_by_name);
756
757 // g_datalist_clear(&fac->named_types);
758 }
759
760 void freeEventtype(LttEventType * evType)
761 {
762 unsigned int i;
763 LttType * root_type;
764 if(evType->description)
765 g_free(evType->description);
766
767 for(i=0; i<evType->fields->len;i++) {
768 LttField *field = &g_array_index(evType->fields, LttField, i);
769 freeLttField(field);
770 }
771 g_array_free(evType->fields, TRUE);
772 g_datalist_clear(&evType->fields_by_name);
773 }
774
775 void freeLttType(LttType * type)
776 {
777 unsigned int i;
778
779 if(type->fmt)
780 g_free(type->fmt);
781
782 if(type->enum_map)
783 g_hash_table_destroy(type->enum_map);
784
785 if(type->fields) {
786 for(i=0; i<type->fields->len; i++) {
787 freeLttField(&g_array_index(type->fields, LttField, i));
788 }
789 g_array_free(type->fields, TRUE);
790 }
791 if(type->fields_by_name)
792 g_datalist_clear(&type->fields_by_name);
793 }
794
795 void freeLttNamedType(LttType * type)
796 {
797 freeLttType(type);
798 }
799
800 void freeLttField(LttField * field)
801 {
802 if(field->description)
803 g_free(field->description);
804 if(field->dynamic_offsets)
805 g_array_free(field->dynamic_offsets, TRUE);
806 freeLttType(&field->field_type);
807 }
808
809 /*****************************************************************************
810 *Function name
811 * ltt_facility_name : obtain the facility's name
812 *Input params
813 * f : the facility
814 *Return value
815 * GQuark : the facility's name
816 ****************************************************************************/
817
818 GQuark ltt_facility_name(LttFacility *f)
819 {
820 return f->name;
821 }
822
823 /*****************************************************************************
824 *Function name
825 * ltt_facility_checksum : obtain the facility's checksum
826 *Input params
827 * f : the facility
828 *Return value
829 * : the checksum of the facility
830 ****************************************************************************/
831
832 guint32 ltt_facility_checksum(LttFacility *f)
833 {
834 return f->checksum;
835 }
836
837 /*****************************************************************************
838 *Function name
839 * ltt_facility_base_id : obtain the facility base id
840 *Input params
841 * f : the facility
842 *Return value
843 * : the base id of the facility
844 ****************************************************************************/
845
846 guint ltt_facility_id(LttFacility *f)
847 {
848 return f->id;
849 }
850
851 /*****************************************************************************
852 *Function name
853 * ltt_facility_eventtype_number: obtain the number of the event types
854 *Input params
855 * f : the facility that will be closed
856 *Return value
857 * : the number of the event types
858 ****************************************************************************/
859
860 guint8 ltt_facility_eventtype_number(LttFacility *f)
861 {
862 return (f->events->len);
863 }
864
865 /*****************************************************************************
866 *Function name
867 * ltt_facility_eventtype_get: obtain the event type according to event id
868 * from 0 to event_number - 1
869 *Input params
870 * f : the facility that will be closed
871 *Return value
872 * LttEventType * : the event type required
873 ****************************************************************************/
874
875 LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i)
876 {
877 if(!f->exists) return NULL;
878
879 g_assert(i < f->events->len);
880 return &g_array_index(f->events, LttEventType, i);
881 }
882
883 /*****************************************************************************
884 *Function name
885 * ltt_facility_eventtype_get_by_name
886 * : obtain the event type according to event name
887 * event name is unique in the facility
888 *Input params
889 * f : the facility
890 * name : the name of the event
891 *Return value
892 * LttEventType * : the event type required
893 ****************************************************************************/
894
895 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name)
896 {
897 LttEventType *et = g_datalist_id_get_data(&f->events_by_name, name);
898 return et;
899 }
900
This page took 0.050583 seconds and 5 git commands to generate.