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