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