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