genevent for 0.1.99.1
[lttv.git] / ltt / branches / poly / ltt-newlib / facility.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
3 * 2005 Mathieu Desnoyers
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
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <glib.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32
33
34 #include "parser.h"
35 #include <ltt/ltt.h>
36 #include "ltt-private.h"
37 #include <ltt/facility.h>
38
39 #ifndef g_open
40 #define g_open open
41 #endif
42
43 #define g_close close
44
45 /* search for the (named) type in the table, if it does not exist
46 create a new one */
47 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
48
49 /* construct directed acyclic graph for types, and tree for fields */
50 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
51 LttField * fld);
52
53 /* generate the facility according to the events belongin to it */
54 void generateFacility(LttFacility * f, facility_t * fac,
55 LttChecksum checksum);
56
57 /* functions to release the memory occupied by a facility */
58 void freeFacility(LttFacility * facility);
59 void freeEventtype(LttEventType * evType);
60 void freeLttType(LttType ** type);
61 void freeLttField(LttField * fld);
62 void freeLttNamedType(LttType * type);
63
64
65 /*****************************************************************************
66 *Function name
67 * ltt_facility_open : open facilities
68 *Input params
69 * t : the trace containing the facilities
70 * pathname : the path name of the facility
71 *
72 *returns 0 on success, 1 on error.
73 ****************************************************************************/
74
75 int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname)
76 {
77 gchar *token;
78 parse_file in;
79 gsize length;
80 facility_t * fac;
81 LttChecksum checksum;
82 GError * error = NULL;
83 gchar buffer[BUFFER_SIZE];
84
85 in.buffer = &(buffer[0]);
86 in.lineno = 0;
87 in.error = error_callback;
88 in.name = pathname;
89
90 in.fd = g_open(in.name, O_RDONLY, 0);
91 if(in.fd < 0 ) {
92 g_warning("cannot open facility description file %s",
93 in.name);
94 return 1;
95 }
96
97 in.channel = g_io_channel_unix_new(in.fd);
98 in.pos = 0;
99
100 while(1){
101 token = getToken(&in);
102 if(in.type == ENDFILE) break;
103
104 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
105 token = getName(&in);
106
107 if(g_ascii_strcasecmp("facility",token) == 0) {
108 fac = g_new(facility_t, 1);
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
118 g_assert(checkNamedTypesImplemented(&fac->named_types) == 0);
119
120 g_assert(generateChecksum(fac->name, &checksum, &fac->events) == 0);
121
122 generateFacility(f, fac, checksum);
123
124 g_free(fac->name);
125 g_free(fac->description);
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);
132 g_free(fac);
133 }
134 else {
135 g_warning("facility token was expected in file %s", in.name);
136 goto parse_error;
137 }
138 }
139
140 parse_error:
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);
148 }
149
150
151 /*****************************************************************************
152 *Function name
153 * generateFacility : generate facility, internal function
154 *Input params
155 * facility : LttFacilty structure
156 * fac : facility structure
157 * checksum : checksum of the facility
158 ****************************************************************************/
159
160 void generateFacility(LttFacility *f, facility_t *fac,LttChecksum checksum)
161 {
162 char * facilityName = fac->name;
163 sequence * events = &fac->events;
164 int i;
165 //LttEventType * evType;
166 LttEventType * event_type;
167 LttField * field;
168 LttType * type;
169
170 g_assert(f->name == g_quark_from_string(facilityName));
171 g_assert(f->checksum == checksum);
172
173 //f->event_number = events->position;
174
175 //initialize inner structures
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);
190
191 //for each event, construct field tree and type graph
192 for(i=0;i<events->position;i++){
193 event_type = &g_array_index(f->events, LttEventType, i);
194 //evType = g_new(LttEventType,1);
195 //f->events[i] = evType;
196
197 event_type->name =
198 g_quark_from_string(((event_t*)(events->array[i]))->name);
199
200 g_datalist_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);
205
206 field = g_new(LttField, 1);
207 event_type->root_field = field;
208 event_type->facility = f;
209 event_type->index = i;
210
211 if(((event_t*)(events->array[i]))->type != NULL){
212 field->field_pos = 0;
213 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
214 field->field_type = type;
215 field->offset_root = 0;
216 field->fixed_root = 1;
217 field->offset_parent = 0;
218 field->fixed_parent = 1;
219 // field->base_address = NULL;
220 field->field_size = 0;
221 field->field_fixed = -1;
222 field->parent = NULL;
223 field->child = NULL;
224 field->current_element = 0;
225
226 //construct field tree and type graph
227 constructTypeAndFields(f,((event_t*)(events->array[i]))->type,field);
228 }else{
229 evType->root_field = NULL;
230 g_free(field);
231 }
232 }
233 }
234
235
236 /*****************************************************************************
237 *Function name
238 * constructTypeAndFields : construct field tree and type graph,
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
246 void constructTypeAndFields(LttFacility * fac, type_descriptor * td,
247 LttField * fld)
248 {
249 int i, flag;
250 type_descriptor * tmpTd;
251
252 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
253 // fld->field_size = 0;
254 // else fld->field_size = -1;
255
256 if(td->type == LTT_ENUM){
257 fld->field_type->element_number = td->labels.position;
258 fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
259 for(i=0;i<td->labels.position;i++){
260 fld->field_type->enum_strings[i]
261 = g_quark_from_string(((char*)(td->labels.array[i])));
262 }
263 }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
264 if(td->type == LTT_ARRAY)
265 fld->field_type->element_number = (unsigned)td->size;
266 fld->field_type->element_type = g_new(LttType*,1);
267 tmpTd = td->nested_type;
268 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
269 fld->child = g_new(LttField*, 1);
270 fld->child[0] = g_new(LttField, 1);
271
272 fld->child[0]->field_pos = 0;
273 fld->child[0]->field_type = fld->field_type->element_type[0];
274 fld->child[0]->offset_root = fld->offset_root;
275 fld->child[0]->fixed_root = fld->fixed_root;
276 fld->child[0]->offset_parent = 0;
277 fld->child[0]->fixed_parent = 1;
278 // fld->child[0]->base_address = NULL;
279 fld->child[0]->field_size = 0;
280 fld->child[0]->field_fixed = -1;
281 fld->child[0]->parent = fld;
282 fld->child[0]->child = NULL;
283 fld->child[0]->current_element = 0;
284 constructTypeAndFields(fac, tmpTd, fld->child[0]);
285 }else if(td->type == LTT_STRUCT){
286 fld->field_type->element_number = td->fields.position;
287
288 if(fld->field_type->element_type == NULL){
289 fld->field_type->element_type = g_new(LttType*, td->fields.position);
290 flag = 1;
291 }else{
292 flag = 0;
293 }
294
295 fld->child = g_new(LttField*, td->fields.position);
296 for(i=0;i<td->fields.position;i++){
297 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
298
299 if(flag)
300 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
301 fld->child[i] = g_new(LttField,1);
302
303 fld->child[i]->field_pos = i;
304 fld->child[i]->field_type = fld->field_type->element_type[i];
305
306 if(flag){
307 fld->child[i]->field_type->element_name
308 = g_quark_from_string(((type_fields*)(td->fields.array[i]))->name);
309 }
310
311 fld->child[i]->offset_root = -1;
312 fld->child[i]->fixed_root = -1;
313 fld->child[i]->offset_parent = -1;
314 fld->child[i]->fixed_parent = -1;
315 // fld->child[i]->base_address = NULL;
316 fld->child[i]->field_size = 0;
317 fld->child[i]->field_fixed = -1;
318 fld->child[i]->parent = fld;
319 fld->child[i]->child = NULL;
320 fld->child[i]->current_element = 0;
321 constructTypeAndFields(fac, tmpTd, fld->child[i]);
322 }
323 }
324 }
325
326
327 /*****************************************************************************
328 *Function name
329 * lookup_named_type: search named type in the table
330 * internal function
331 *Input params
332 * fac : facility struct
333 * td : type descriptor
334 *Return value
335 * : either find the named type, or create a new LttType
336 ****************************************************************************/
337
338 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
339 {
340 GQuark name = g_quark_from_string(td->type_name);
341
342 LttType *type = g_datalist_get_data(fac->named_types_by_name, name);
343
344 if(type == NULL){
345 type = g_new(LttType,1);
346 type->type_name = name;
347 g_datalist_set_data_full(fac->named_types, name,
348 type, freeLttNamedType);
349 type->type_class = td->type;
350 if(td->fmt) type->fmt = g_strdup(td->fmt);
351 else type->fmt = NULL;
352 type->size = td->size;
353 type->enum_strings = NULL;
354 type->element_type = NULL;
355 type->element_number = 0;
356 }
357
358 return type;
359 }
360
361
362 /*****************************************************************************
363 *Function name
364 * ltt_facility_close : close a facility, decrease its usage count,
365 * if usage count = 0, release the memory
366 *Input params
367 * f : facility that will be closed
368 ****************************************************************************/
369
370 void ltt_facility_close(LttFacility *f)
371 {
372 //release the memory it occupied
373 freeFacility(f);
374 }
375
376 /*****************************************************************************
377 * Functions to release the memory occupied by the facility
378 ****************************************************************************/
379
380 void freeFacility(LttFacility * fac)
381 {
382 guint i;
383 LttEventType *et;
384
385 for(i=0; i<fac->events->len; i++) {
386 et = &g_array_index (fac->events, LttEventType, i);
387 freeEventtype(et);
388 }
389 g_array_free(fac->events);
390
391 g_datalist_clear(fac->named_types);
392
393 }
394
395 void freeEventtype(LttEventType * evType)
396 {
397 LttType * root_type;
398 if(evType->description)
399 g_free(evType->description);
400 if(evType->root_field){
401 root_type = evType->root_field->field_type;
402 freeLttField(evType->root_field);
403 freeLttType(&root_type);
404 }
405 }
406
407 void freeLttNamedType(LttType * type)
408 {
409 freeLttType(&type);
410 }
411
412 void freeLttType(LttType ** type)
413 {
414 unsigned int i;
415 if(*type == NULL) return;
416 //if((*type)->type_name){
417 // return; //this is a named type
418 //}
419 if((*type)->fmt)
420 g_free((*type)->fmt);
421 if((*type)->enum_strings){
422 g_free((*type)->enum_strings);
423 }
424
425 if((*type)->element_type){
426 for(i=0;i<(*type)->element_number;i++)
427 freeLttType(&((*type)->element_type[i]));
428 g_free((*type)->element_type);
429 }
430 g_free(*type);
431 *type = NULL;
432 }
433
434 void freeLttField(LttField * fld)
435 {
436 int i;
437 int size = 0;
438
439 if(fld->field_type){
440 if(fld->field_type->type_class == LTT_ARRAY ||
441 fld->field_type->type_class == LTT_SEQUENCE){
442 size = 1;
443 }else if(fld->field_type->type_class == LTT_STRUCT){
444 size = fld->field_type->element_number;
445 }
446 }
447
448 if(fld->child){
449 for(i=0; i<size; i++){
450 if(fld->child[i])freeLttField(fld->child[i]);
451 }
452 g_free(fld->child);
453 }
454 g_free(fld);
455 }
456
457 /*****************************************************************************
458 *Function name
459 * ltt_facility_name : obtain the facility's name
460 *Input params
461 * f : the facility
462 *Return value
463 * GQuark : the facility's name
464 ****************************************************************************/
465
466 GQuark ltt_facility_name(LttFacility *f)
467 {
468 return f->name;
469 }
470
471 /*****************************************************************************
472 *Function name
473 * ltt_facility_checksum : obtain the facility's checksum
474 *Input params
475 * f : the facility
476 *Return value
477 * LttChecksum : the checksum of the facility
478 ****************************************************************************/
479
480 LttChecksum ltt_facility_checksum(LttFacility *f)
481 {
482 return f->checksum;
483 }
484
485 /*****************************************************************************
486 *Function name
487 * ltt_facility_base_id : obtain the facility base id
488 *Input params
489 * f : the facility
490 *Return value
491 * : the base id of the facility
492 ****************************************************************************/
493
494 guint ltt_facility_id(LttFacility *f)
495 {
496 return f->id;
497 }
498
499 /*****************************************************************************
500 *Function name
501 * ltt_facility_eventtype_number: obtain the number of the event types
502 *Input params
503 * f : the facility that will be closed
504 *Return value
505 * : the number of the event types
506 ****************************************************************************/
507
508 guint ltt_facility_eventtype_number(LttFacility *f)
509 {
510 return (f->events->len);
511 }
512
513 /*****************************************************************************
514 *Function name
515 * ltt_facility_eventtype_get: obtain the event type according to event id
516 * from 0 to event_number - 1
517 *Input params
518 * f : the facility that will be closed
519 *Return value
520 * LttEventType * : the event type required
521 ****************************************************************************/
522
523 LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i)
524 {
525 g_assert(i < f->events->len);
526 return &g_array_index(f->events, LttEventType, i);
527 }
528
529 /*****************************************************************************
530 *Function name
531 * ltt_facility_eventtype_get_by_name
532 * : obtain the event type according to event name
533 * event name is unique in the facility
534 *Input params
535 * f : the facility
536 * name : the name of the event
537 *Return value
538 * LttEventType * : the event type required
539 ****************************************************************************/
540
541 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name)
542 {
543 LttEventType *et = g_datalist_get_data(fac->events_by_name, name);
544 }
545
This page took 0.041431 seconds and 4 git commands to generate.