fix include names for 2.4 compatibility
[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 *
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
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <glib.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26
27
28
29 #include "parser.h"
30 #include <ltt/ltt.h>
31 #include "ltt-private.h"
32 #include <ltt/facility.h>
33
34 #ifndef g_open
35 #define g_open open
36 #endif
37
38 #define g_close close
39
40 /* search for the (named) type in the table, if it does not exist
41 create a new one */
42 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
43
44 /* construct directed acyclic graph for types, and tree for fields */
45 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
46 LttField * fld);
47
48 /* generate the facility according to the events belongin to it */
49 void generateFacility(LttFacility * f, facility_t * fac,
50 LttChecksum checksum);
51
52 /* functions to release the memory occupied by a facility */
53 void freeFacility(LttFacility * facility);
54 void freeEventtype(LttEventType * evType);
55 void freeLttType(LttType ** type);
56 void freeLttField(LttField * fld);
57 void freeLttNamedType(LttType * type);
58
59
60 /*****************************************************************************
61 *Function name
62 * ltt_facility_open : open facilities
63 *Input params
64 * t : the trace containing the facilities
65 * pathname : the path name of the facility
66 ****************************************************************************/
67
68 void ltt_facility_open(LttTrace * t, gchar * pathname)
69 {
70 gchar *token;
71 parse_file in;
72 gsize length;
73 facility_t * fac;
74 LttFacility * f;
75 LttChecksum checksum;
76 GError * error = NULL;
77 gchar buffer[BUFFER_SIZE];
78
79 in.buffer = &(buffer[0]);
80 in.lineno = 0;
81 in.error = error_callback;
82 in.name = pathname;
83
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;
89
90 while(1){
91 token = getToken(&in);
92 if(in.type == ENDFILE) break;
93
94 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
95 token = getName(&in);
96
97 if(g_ascii_strcasecmp("facility",token) == 0) {
98 fac = g_new(facility_t, 1);
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
108 g_assert(checkNamedTypesImplemented(&fac->named_types) == 0);
109
110 g_assert(generateChecksum(fac->name, &checksum, &fac->events) == 0);
111
112 f = g_new(LttFacility,1);
113 f->base_id = 0;
114 generateFacility(f, fac, checksum);
115
116 t->facility_number++;
117 g_ptr_array_add(t->facilities,f);
118
119 g_free(fac->name);
120 g_free(fac->description);
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);
127 g_free(fac);
128 }
129 else in.error(&in,"facility token was expected");
130 }
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);
139 }
140
141
142 /*****************************************************************************
143 *Function name
144 * generateFacility : generate facility, internal function
145 *Input params
146 * facility : LttFacilty structure
147 * fac : facility structure
148 * checksum : checksum of the facility
149 ****************************************************************************/
150
151 void generateFacility(LttFacility *f, facility_t *fac,LttChecksum checksum)
152 {
153 char * facilityName = fac->name;
154 sequence * events = &fac->events;
155 int i;
156 LttEventType * evType;
157 LttField * field;
158 LttType * type;
159
160 f->name = g_strdup(facilityName);
161 f->event_number = events->position;
162 f->checksum = checksum;
163
164 //initialize inner structures
165 f->events = g_new(LttEventType*,f->event_number);
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;
169
170 //for each event, construct field tree and type graph
171 for(i=0;i<events->position;i++){
172 evType = g_new(LttEventType,1);
173 f->events[i] = evType;
174
175 evType->name = g_strdup(((event_t*)(events->array[i]))->name);
176 evType->description=g_strdup(((event_t*)(events->array[i]))->description);
177
178 field = g_new(LttField, 1);
179 evType->root_field = field;
180 evType->facility = f;
181 evType->index = i;
182
183 if(((event_t*)(events->array[i]))->type != NULL){
184 field->field_pos = 0;
185 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
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;
197
198 //construct field tree and type graph
199 constructTypeAndFields(f,((event_t*)(events->array[i]))->type,field);
200 }else{
201 evType->root_field = NULL;
202 g_free(field);
203 }
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
218 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
219 LttField * fld)
220 {
221 int i, flag;
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;
238 fld->field_type->element_type = g_new(LttType*,1);
239 tmpTd = td->nested_type;
240 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
241 fld->child = g_new(LttField*, 1);
242 fld->child[0] = g_new(LttField, 1);
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;
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
267 fld->child = g_new(LttField*, td->fields.position);
268 for(i=0;i<td->fields.position;i++){
269 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
270
271 if(flag)
272 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
273 fld->child[i] = g_new(LttField,1);
274
275 fld->child[i]->field_pos = i;
276 fld->child[i]->field_type = fld->field_type->element_type[i];
277
278 if(flag){
279 fld->child[i]->field_type->element_name
280 = g_strdup(((type_fields*)(td->fields.array[i]))->name);
281 }
282
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
307 * : either find the named type, or create a new LttType
308 ****************************************************************************/
309
310 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
311 {
312 LttType * lttType = NULL;
313 unsigned int i=0;
314 gchar * name;
315
316 if(td->type_name){
317 for(i=0;i<fac->named_types_number; i++){
318 if(fac->named_types[i] == NULL) break;
319 name = fac->named_types[i]->type_name;
320 if(g_ascii_strcasecmp(name, td->type_name)==0){
321 lttType = fac->named_types[i];
322 // if(lttType->element_name) g_free(lttType->element_name);
323 // lttType->element_name = NULL;
324 break;
325 }
326 }
327 }
328
329 if(!lttType){
330 lttType = g_new(LttType,1);
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;
338 lttType->element_name = NULL;
339 if(td->type_name){
340 lttType->type_name = g_strdup(td->type_name);
341 fac->named_types[i] = lttType; /* i is initialized, checked. */
342 }
343 else{
344 lttType->type_name = NULL;
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
362 int ltt_facility_close(LttFacility *f)
363 {
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
374 void freeFacility(LttFacility * fac)
375 {
376 unsigned int i;
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 }
383 g_free(fac->events);
384
385 //free all named types
386 for(i=0;i<fac->named_types_number;i++){
387 freeLttNamedType(fac->named_types[i]);
388 fac->named_types[i] = NULL;
389 }
390 g_free(fac->named_types);
391
392 //free the facility itself
393 g_free(fac);
394 }
395
396 void freeEventtype(LttEventType * evType)
397 {
398 LttType * root_type;
399 g_free(evType->name);
400 if(evType->description)
401 g_free(evType->description);
402 if(evType->root_field){
403 root_type = evType->root_field->field_type;
404 freeLttField(evType->root_field);
405 freeLttType(&root_type);
406 }
407
408 g_free(evType);
409 }
410
411 void freeLttNamedType(LttType * type)
412 {
413 g_free(type->type_name);
414 type->type_name = NULL;
415 freeLttType(&type);
416 }
417
418 void freeLttType(LttType ** type)
419 {
420 unsigned int i;
421 if(*type == NULL) return;
422 if((*type)->type_name){
423 return; //this is a named type
424 }
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);
433 }
434
435 if((*type)->element_type){
436 for(i=0;i<(*type)->element_number;i++)
437 freeLttType(&((*type)->element_type[i]));
438 g_free((*type)->element_type);
439 }
440 g_free(*type);
441 *type = NULL;
442 }
443
444 void freeLttField(LttField * fld)
445 {
446 int i;
447 int size = 0;
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 }
456 }
457
458 if(fld->child){
459 for(i=0; i<size; i++){
460 if(fld->child[i])freeLttField(fld->child[i]);
461 }
462 g_free(fld->child);
463 }
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
476 gchar *ltt_facility_name(LttFacility *f)
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
487 * LttChecksum : the checksum of the facility
488 ****************************************************************************/
489
490 LttChecksum ltt_facility_checksum(LttFacility *f)
491 {
492 return f->checksum;
493 }
494
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
504 unsigned ltt_facility_base_id(LttFacility *f)
505 {
506 return f->base_id;
507 }
508
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
518 unsigned ltt_facility_eventtype_number(LttFacility *f)
519 {
520 return (f->event_number);
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
530 * LttEventType * : the event type required
531 ****************************************************************************/
532
533 LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
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
544 * f : the facility
545 * name : the name of the event
546 *Return value
547 * LttEventType * : the event type required
548 ****************************************************************************/
549
550 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, gchar *name)
551 {
552 unsigned int i;
553 LttEventType * ev = NULL;
554
555 for(i=0;i<f->event_number;i++){
556 LttEventType *iter_ev = f->events[i];
557 if(g_ascii_strcasecmp(iter_ev->name, name) == 0) {
558 ev = iter_ev;
559 break;
560 }
561 }
562 return ev;
563 }
564
This page took 0.05612 seconds and 5 git commands to generate.