header missing
[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
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
6cd62ccf 19#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
cdf90f40 22#include <glib.h>
45e14832 23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26
27
6cd62ccf 28
6cd62ccf 29#include "parser.h"
a5dcde2f 30#include <ltt/ltt.h>
31#include "ltt-private.h"
6cd62ccf 32#include <ltt/facility.h>
33
86005ded 34#ifndef g_open
35#define g_open open
36#endif
37
45e14832 38#define g_close close
39
6cd62ccf 40/* search for the (named) type in the table, if it does not exist
41 create a new one */
963b5f2d 42LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
6cd62ccf 43
44/* construct directed acyclic graph for types, and tree for fields */
963b5f2d 45void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
46 LttField * fld);
6cd62ccf 47
48/* generate the facility according to the events belongin to it */
8d1e6362 49void generateFacility(LttFacility * f, facility_t * fac,
963b5f2d 50 LttChecksum checksum);
6cd62ccf 51
52/* functions to release the memory occupied by a facility */
963b5f2d 53void freeFacility(LttFacility * facility);
54void freeEventtype(LttEventType * evType);
1417d990 55void freeLttType(LttType ** type);
963b5f2d 56void freeLttField(LttField * fld);
908f42fa 57void freeLttNamedType(LttType * type);
6cd62ccf 58
59
60/*****************************************************************************
61 *Function name
963b5f2d 62 * ltt_facility_open : open facilities
6cd62ccf 63 *Input params
963b5f2d 64 * t : the trace containing the facilities
6cd62ccf 65 * pathname : the path name of the facility
6cd62ccf 66 ****************************************************************************/
67
45e14832 68void ltt_facility_open(LttTrace * t, gchar * pathname)
6cd62ccf 69{
45e14832 70 gchar *token;
6cd62ccf 71 parse_file in;
45e14832 72 gsize length;
8d1e6362 73 facility_t * fac;
963b5f2d 74 LttFacility * f;
75 LttChecksum checksum;
45e14832 76 GError * error = NULL;
77 gchar buffer[BUFFER_SIZE];
6cd62ccf 78
45e14832 79 in.buffer = &(buffer[0]);
6cd62ccf 80 in.lineno = 0;
81 in.error = error_callback;
963b5f2d 82 in.name = pathname;
6cd62ccf 83
45e14832 84 in.fd = g_open(in.name, O_RDONLY, 0);
85 if(in.fd < 0 ) in.error(&in,"cannot open input file");
86
87 in.channel = g_io_channel_unix_new(in.fd);
88 in.pos = 0;
963b5f2d 89
6cd62ccf 90 while(1){
91 token = getToken(&in);
92 if(in.type == ENDFILE) break;
93
45e14832 94 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
963b5f2d 95 token = getName(&in);
45e14832 96
97 if(g_ascii_strcasecmp("facility",token) == 0) {
8d1e6362 98 fac = g_new(facility_t, 1);
963b5f2d 99 fac->name = NULL;
100 fac->description = NULL;
101 sequence_init(&(fac->events));
102 table_init(&(fac->named_types));
103 sequence_init(&(fac->unnamed_types));
104
105 parseFacility(&in, fac);
106
107 //check if any namedType is not defined
fc063e40 108 g_assert(checkNamedTypesImplemented(&fac->named_types) == 0);
963b5f2d 109
fc063e40 110 g_assert(generateChecksum(fac->name, &checksum, &fac->events) == 0);
963b5f2d 111
112 f = g_new(LttFacility,1);
fe974fde 113 f->base_id = 0;
963b5f2d 114 generateFacility(f, fac, checksum);
115
116 t->facility_number++;
117 g_ptr_array_add(t->facilities,f);
118
45e14832 119 g_free(fac->name);
120 g_free(fac->description);
963b5f2d 121 freeEvents(&fac->events);
122 sequence_dispose(&fac->events);
123 freeNamedType(&fac->named_types);
124 table_dispose(&fac->named_types);
125 freeTypes(&fac->unnamed_types);
126 sequence_dispose(&fac->unnamed_types);
cf1307af 127 g_free(fac);
6cd62ccf 128 }
963b5f2d 129 else in.error(&in,"facility token was expected");
6cd62ccf 130 }
45e14832 131
132 g_io_channel_shutdown(in.channel, FALSE, &error); /* No flush */
133 if(error != NULL) {
134 g_warning("Can not close file: \n%s\n", error->message);
135 g_error_free(error);
136 }
137
138 g_close(in.fd);
6cd62ccf 139}
140
141
142/*****************************************************************************
143 *Function name
144 * generateFacility : generate facility, internal function
145 *Input params
963b5f2d 146 * facility : LttFacilty structure
147 * fac : facility structure
6cd62ccf 148 * checksum : checksum of the facility
6cd62ccf 149 ****************************************************************************/
150
8d1e6362 151void generateFacility(LttFacility *f, facility_t *fac,LttChecksum checksum)
6cd62ccf 152{
963b5f2d 153 char * facilityName = fac->name;
154 sequence * events = &fac->events;
6cd62ccf 155 int i;
963b5f2d 156 LttEventType * evType;
157 LttField * field;
158 LttType * type;
6cd62ccf 159
963b5f2d 160 f->name = g_strdup(facilityName);
161 f->event_number = events->position;
162 f->checksum = checksum;
6cd62ccf 163
164 //initialize inner structures
963b5f2d 165 f->events = g_new(LttEventType*,f->event_number);
1417d990 166 f->named_types_number = fac->named_types.keys.position;
167 f->named_types = g_new(LttType*, fac->named_types.keys.position);
168 for(i=0;i<fac->named_types.keys.position;i++) f->named_types[i] = NULL;
6cd62ccf 169
170 //for each event, construct field tree and type graph
171 for(i=0;i<events->position;i++){
963b5f2d 172 evType = g_new(LttEventType,1);
173 f->events[i] = evType;
6cd62ccf 174
8d1e6362 175 evType->name = g_strdup(((event_t*)(events->array[i]))->name);
176 evType->description=g_strdup(((event_t*)(events->array[i]))->description);
6cd62ccf 177
963b5f2d 178 field = g_new(LttField, 1);
6cd62ccf 179 evType->root_field = field;
963b5f2d 180 evType->facility = f;
6cd62ccf 181 evType->index = i;
182
8d1e6362 183 if(((event_t*)(events->array[i]))->type != NULL){
8710c6c7 184 field->field_pos = 0;
8d1e6362 185 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
8710c6c7 186 field->field_type = type;
187 field->offset_root = 0;
188 field->fixed_root = 1;
189 field->offset_parent = 0;
190 field->fixed_parent = 1;
191 // field->base_address = NULL;
192 field->field_size = 0;
193 field->field_fixed = -1;
194 field->parent = NULL;
195 field->child = NULL;
196 field->current_element = 0;
72a508f8 197
8710c6c7 198 //construct field tree and type graph
8d1e6362 199 constructTypeAndFields(f,((event_t*)(events->array[i]))->type,field);
8710c6c7 200 }else{
72a508f8 201 evType->root_field = NULL;
8710c6c7 202 g_free(field);
203 }
6cd62ccf 204 }
205}
206
207
208/*****************************************************************************
209 *Function name
210 * constructTypeAndFields : construct field tree and type graph,
211 * internal recursion function
212 *Input params
213 * fac : facility struct
214 * td : type descriptor
215 * root_field : root field of the event
216 ****************************************************************************/
217
963b5f2d 218void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
219 LttField * fld)
6cd62ccf 220{
908f42fa 221 int i, flag;
6cd62ccf 222 type_descriptor * tmpTd;
223
224 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
225 // fld->field_size = 0;
226 // else fld->field_size = -1;
227
228 if(td->type == LTT_ENUM){
229 fld->field_type->element_number = td->labels.position;
230 fld->field_type->enum_strings = g_new(char*,td->labels.position);
231 for(i=0;i<td->labels.position;i++){
232 fld->field_type->enum_strings[i]
233 = g_strdup(((char*)(td->labels.array[i])));
234 }
235 }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
236 if(td->type == LTT_ARRAY)
237 fld->field_type->element_number = (unsigned)td->size;
963b5f2d 238 fld->field_type->element_type = g_new(LttType*,1);
6cd62ccf 239 tmpTd = td->nested_type;
240 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
963b5f2d 241 fld->child = g_new(LttField*, 1);
242 fld->child[0] = g_new(LttField, 1);
6cd62ccf 243
244 fld->child[0]->field_pos = 0;
245 fld->child[0]->field_type = fld->field_type->element_type[0];
246 fld->child[0]->offset_root = fld->offset_root;
247 fld->child[0]->fixed_root = fld->fixed_root;
248 fld->child[0]->offset_parent = 0;
249 fld->child[0]->fixed_parent = 1;
250 // fld->child[0]->base_address = NULL;
251 fld->child[0]->field_size = 0;
252 fld->child[0]->field_fixed = -1;
253 fld->child[0]->parent = fld;
254 fld->child[0]->child = NULL;
255 fld->child[0]->current_element = 0;
256 constructTypeAndFields(fac, tmpTd, fld->child[0]);
257 }else if(td->type == LTT_STRUCT){
258 fld->field_type->element_number = td->fields.position;
908f42fa 259
260 if(fld->field_type->element_type == NULL){
261 fld->field_type->element_type = g_new(LttType*, td->fields.position);
262 flag = 1;
263 }else{
264 flag = 0;
265 }
266
963b5f2d 267 fld->child = g_new(LttField*, td->fields.position);
6cd62ccf 268 for(i=0;i<td->fields.position;i++){
8d1e6362 269 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
908f42fa 270
271 if(flag)
272 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
963b5f2d 273 fld->child[i] = g_new(LttField,1);
6cd62ccf 274
275 fld->child[i]->field_pos = i;
276 fld->child[i]->field_type = fld->field_type->element_type[i];
908f42fa 277
278 if(flag){
279 fld->child[i]->field_type->element_name
8d1e6362 280 = g_strdup(((type_fields*)(td->fields.array[i]))->name);
908f42fa 281 }
282
6cd62ccf 283 fld->child[i]->offset_root = -1;
284 fld->child[i]->fixed_root = -1;
285 fld->child[i]->offset_parent = -1;
286 fld->child[i]->fixed_parent = -1;
287 // fld->child[i]->base_address = NULL;
288 fld->child[i]->field_size = 0;
289 fld->child[i]->field_fixed = -1;
290 fld->child[i]->parent = fld;
291 fld->child[i]->child = NULL;
292 fld->child[i]->current_element = 0;
293 constructTypeAndFields(fac, tmpTd, fld->child[i]);
294 }
295 }
296}
297
298
299/*****************************************************************************
300 *Function name
301 * lookup_named_type: search named type in the table
302 * internal function
303 *Input params
304 * fac : facility struct
305 * td : type descriptor
306 *Return value
963b5f2d 307 * : either find the named type, or create a new LttType
6cd62ccf 308 ****************************************************************************/
309
963b5f2d 310LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
6cd62ccf 311{
963b5f2d 312 LttType * lttType = NULL;
cf74a6f1 313 unsigned int i=0;
45e14832 314 gchar * name;
cf74a6f1 315
6cd62ccf 316 if(td->type_name){
1417d990 317 for(i=0;i<fac->named_types_number; i++){
318 if(fac->named_types[i] == NULL) break;
908f42fa 319 name = fac->named_types[i]->type_name;
45e14832 320 if(g_ascii_strcasecmp(name, td->type_name)==0){
cf74a6f1 321 lttType = fac->named_types[i];
908f42fa 322 // if(lttType->element_name) g_free(lttType->element_name);
323 // lttType->element_name = NULL;
cf74a6f1 324 break;
6cd62ccf 325 }
326 }
327 }
328
329 if(!lttType){
963b5f2d 330 lttType = g_new(LttType,1);
6cd62ccf 331 lttType->type_class = td->type;
332 if(td->fmt) lttType->fmt = g_strdup(td->fmt);
333 else lttType->fmt = NULL;
334 lttType->size = td->size;
335 lttType->enum_strings = NULL;
336 lttType->element_type = NULL;
337 lttType->element_number = 0;
908f42fa 338 lttType->element_name = NULL;
6cd62ccf 339 if(td->type_name){
908f42fa 340 lttType->type_name = g_strdup(td->type_name);
cf74a6f1 341 fac->named_types[i] = lttType; /* i is initialized, checked. */
6cd62ccf 342 }
343 else{
908f42fa 344 lttType->type_name = NULL;
6cd62ccf 345 }
346 }
347
348 return lttType;
349}
350
351
352/*****************************************************************************
353 *Function name
354 * ltt_facility_close : close a facility, decrease its usage count,
355 * if usage count = 0, release the memory
356 *Input params
357 * f : facility that will be closed
358 *Return value
359 * int : usage count ?? status
360 ****************************************************************************/
361
963b5f2d 362int ltt_facility_close(LttFacility *f)
6cd62ccf 363{
6cd62ccf 364 //release the memory it occupied
365 freeFacility(f);
366
367 return 0;
368}
369
370/*****************************************************************************
371 * Functions to release the memory occupied by the facility
372 ****************************************************************************/
373
963b5f2d 374void freeFacility(LttFacility * fac)
6cd62ccf 375{
8d1e6362 376 unsigned int i;
6cd62ccf 377 g_free(fac->name); //free facility name
378
379 //free event types
380 for(i=0;i<fac->event_number;i++){
381 freeEventtype(fac->events[i]);
382 }
963b5f2d 383 g_free(fac->events);
6cd62ccf 384
385 //free all named types
908f42fa 386 for(i=0;i<fac->named_types_number;i++){
387 freeLttNamedType(fac->named_types[i]);
388 fac->named_types[i] = NULL;
389 }
1417d990 390 g_free(fac->named_types);
6cd62ccf 391
392 //free the facility itself
393 g_free(fac);
394}
395
963b5f2d 396void freeEventtype(LttEventType * evType)
6cd62ccf 397{
908f42fa 398 LttType * root_type;
6cd62ccf 399 g_free(evType->name);
400 if(evType->description)
401 g_free(evType->description);
1417d990 402 if(evType->root_field){
908f42fa 403 root_type = evType->root_field->field_type;
1417d990 404 freeLttField(evType->root_field);
908f42fa 405 freeLttType(&root_type);
1417d990 406 }
407
6cd62ccf 408 g_free(evType);
409}
410
908f42fa 411void freeLttNamedType(LttType * type)
412{
908f42fa 413 g_free(type->type_name);
414 type->type_name = NULL;
415 freeLttType(&type);
416}
417
1417d990 418void freeLttType(LttType ** type)
6cd62ccf 419{
8d1e6362 420 unsigned int i;
1417d990 421 if(*type == NULL) return;
908f42fa 422 if((*type)->type_name){
423 return; //this is a named type
424 }
1417d990 425 if((*type)->element_name)
426 g_free((*type)->element_name);
427 if((*type)->fmt)
428 g_free((*type)->fmt);
429 if((*type)->enum_strings){
430 for(i=0;i<(*type)->element_number;i++)
431 g_free((*type)->enum_strings[i]);
432 g_free((*type)->enum_strings);
6cd62ccf 433 }
6cd62ccf 434
1417d990 435 if((*type)->element_type){
908f42fa 436 for(i=0;i<(*type)->element_number;i++)
437 freeLttType(&((*type)->element_type[i]));
1417d990 438 g_free((*type)->element_type);
6cd62ccf 439 }
1417d990 440 g_free(*type);
441 *type = NULL;
6cd62ccf 442}
443
1417d990 444void freeLttField(LttField * fld)
445{
963b5f2d 446 int i;
908f42fa 447 int size = 0;
1417d990 448
449 if(fld->field_type){
450 if(fld->field_type->type_class == LTT_ARRAY ||
451 fld->field_type->type_class == LTT_SEQUENCE){
452 size = 1;
453 }else if(fld->field_type->type_class == LTT_STRUCT){
454 size = fld->field_type->element_number;
455 }
963b5f2d 456 }
6cd62ccf 457
1417d990 458 if(fld->child){
459 for(i=0; i<size; i++){
460 if(fld->child[i])freeLttField(fld->child[i]);
461 }
6cd62ccf 462 g_free(fld->child);
1417d990 463 }
6cd62ccf 464 g_free(fld);
465}
466
467/*****************************************************************************
468 *Function name
469 * ltt_facility_name : obtain the facility's name
470 *Input params
471 * f : the facility that will be closed
472 *Return value
473 * char * : the facility's name
474 ****************************************************************************/
475
45e14832 476gchar *ltt_facility_name(LttFacility *f)
6cd62ccf 477{
478 return f->name;
479}
480
481/*****************************************************************************
482 *Function name
483 * ltt_facility_checksum : obtain the facility's checksum
484 *Input params
485 * f : the facility that will be closed
486 *Return value
963b5f2d 487 * LttChecksum : the checksum of the facility
6cd62ccf 488 ****************************************************************************/
489
963b5f2d 490LttChecksum ltt_facility_checksum(LttFacility *f)
6cd62ccf 491{
492 return f->checksum;
493}
494
963b5f2d 495/*****************************************************************************
496 *Function name
497 * ltt_facility_base_id : obtain the facility base id
498 *Input params
499 * f : the facility
500 *Return value
501 * : the base id of the facility
502 ****************************************************************************/
503
504unsigned ltt_facility_base_id(LttFacility *f)
505{
506 return f->base_id;
507}
508
6cd62ccf 509/*****************************************************************************
510 *Function name
511 * ltt_facility_eventtype_number: obtain the number of the event types
512 *Input params
513 * f : the facility that will be closed
514 *Return value
515 * unsigned : the number of the event types
516 ****************************************************************************/
517
963b5f2d 518unsigned ltt_facility_eventtype_number(LttFacility *f)
6cd62ccf 519{
8d1e6362 520 return (f->event_number);
6cd62ccf 521}
522
523/*****************************************************************************
524 *Function name
525 * ltt_facility_eventtype_get: obtain the event type according to event id
526 * from 0 to event_number - 1
527 *Input params
528 * f : the facility that will be closed
529 *Return value
963b5f2d 530 * LttEventType * : the event type required
6cd62ccf 531 ****************************************************************************/
532
963b5f2d 533LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
6cd62ccf 534{
535 return f->events[i];
536}
537
538/*****************************************************************************
539 *Function name
540 * ltt_facility_eventtype_get_by_name
541 * : obtain the event type according to event name
542 * event name is unique in the facility
543 *Input params
cf74a6f1 544 * f : the facility
6cd62ccf 545 * name : the name of the event
546 *Return value
963b5f2d 547 * LttEventType * : the event type required
6cd62ccf 548 ****************************************************************************/
549
45e14832 550LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, gchar *name)
6cd62ccf 551{
8d1e6362 552 unsigned int i;
cf74a6f1 553 LttEventType * ev = NULL;
554
6cd62ccf 555 for(i=0;i<f->event_number;i++){
cf74a6f1 556 LttEventType *iter_ev = f->events[i];
45e14832 557 if(g_ascii_strcasecmp(iter_ev->name, name) == 0) {
cf74a6f1 558 ev = iter_ev;
559 break;
560 }
6cd62ccf 561 }
cf74a6f1 562 return ev;
6cd62ccf 563}
564
This page took 0.056795 seconds and 4 git commands to generate.