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