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