Add config.h support : will fix the LARGEFILE problem
[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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <glib.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30
31
32
33 #include "parser.h"
34 #include <ltt/ltt.h>
35 #include "ltt-private.h"
36 #include <ltt/facility.h>
37
38 #ifndef g_open
39 #define g_open open
40 #endif
41
42 #define g_close close
43
44 /* search for the (named) type in the table, if it does not exist
45 create a new one */
46 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
47
48 /* construct directed acyclic graph for types, and tree for fields */
49 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
50 LttField * fld);
51
52 /* generate the facility according to the events belongin to it */
53 void generateFacility(LttFacility * f, facility_t * fac,
54 LttChecksum checksum);
55
56 /* functions to release the memory occupied by a facility */
57 void freeFacility(LttFacility * facility);
58 void freeEventtype(LttEventType * evType);
59 void freeLttType(LttType ** type);
60 void freeLttField(LttField * fld);
61 void freeLttNamedType(LttType * type);
62
63
64 /*****************************************************************************
65 *Function name
66 * ltt_facility_open : open facilities
67 *Input params
68 * t : the trace containing the facilities
69 * pathname : the path name of the facility
70 ****************************************************************************/
71
72 void ltt_facility_open(LttTrace * t, gchar * pathname)
73 {
74 gchar *token;
75 parse_file in;
76 gsize length;
77 facility_t * fac;
78 LttFacility * f;
79 LttChecksum checksum;
80 GError * error = NULL;
81 gchar buffer[BUFFER_SIZE];
82
83 in.buffer = &(buffer[0]);
84 in.lineno = 0;
85 in.error = error_callback;
86 in.name = pathname;
87
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;
93
94 while(1){
95 token = getToken(&in);
96 if(in.type == ENDFILE) break;
97
98 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
99 token = getName(&in);
100
101 if(g_ascii_strcasecmp("facility",token) == 0) {
102 fac = g_new(facility_t, 1);
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
112 g_assert(checkNamedTypesImplemented(&fac->named_types) == 0);
113
114 g_assert(generateChecksum(fac->name, &checksum, &fac->events) == 0);
115
116 f = g_new(LttFacility,1);
117 f->base_id = 0;
118 generateFacility(f, fac, checksum);
119
120 t->facility_number++;
121 g_ptr_array_add(t->facilities,f);
122
123 g_free(fac->name);
124 g_free(fac->description);
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);
131 g_free(fac);
132 }
133 else in.error(&in,"facility token was expected");
134 }
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);
143 }
144
145
146 /*****************************************************************************
147 *Function name
148 * generateFacility : generate facility, internal function
149 *Input params
150 * facility : LttFacilty structure
151 * fac : facility structure
152 * checksum : checksum of the facility
153 ****************************************************************************/
154
155 void generateFacility(LttFacility *f, facility_t *fac,LttChecksum checksum)
156 {
157 char * facilityName = fac->name;
158 sequence * events = &fac->events;
159 int i;
160 LttEventType * evType;
161 LttField * field;
162 LttType * type;
163
164 f->name = g_strdup(facilityName);
165 f->event_number = events->position;
166 f->checksum = checksum;
167
168 //initialize inner structures
169 f->events = g_new(LttEventType*,f->event_number);
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;
173
174 //for each event, construct field tree and type graph
175 for(i=0;i<events->position;i++){
176 evType = g_new(LttEventType,1);
177 f->events[i] = evType;
178
179 evType->name = g_strdup(((event_t*)(events->array[i]))->name);
180 evType->description=g_strdup(((event_t*)(events->array[i]))->description);
181
182 field = g_new(LttField, 1);
183 evType->root_field = field;
184 evType->facility = f;
185 evType->index = i;
186
187 if(((event_t*)(events->array[i]))->type != NULL){
188 field->field_pos = 0;
189 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
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;
201
202 //construct field tree and type graph
203 constructTypeAndFields(f,((event_t*)(events->array[i]))->type,field);
204 }else{
205 evType->root_field = NULL;
206 g_free(field);
207 }
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
222 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
223 LttField * fld)
224 {
225 int i, flag;
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;
242 fld->field_type->element_type = g_new(LttType*,1);
243 tmpTd = td->nested_type;
244 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
245 fld->child = g_new(LttField*, 1);
246 fld->child[0] = g_new(LttField, 1);
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;
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
271 fld->child = g_new(LttField*, td->fields.position);
272 for(i=0;i<td->fields.position;i++){
273 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
274
275 if(flag)
276 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
277 fld->child[i] = g_new(LttField,1);
278
279 fld->child[i]->field_pos = i;
280 fld->child[i]->field_type = fld->field_type->element_type[i];
281
282 if(flag){
283 fld->child[i]->field_type->element_name
284 = g_strdup(((type_fields*)(td->fields.array[i]))->name);
285 }
286
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
311 * : either find the named type, or create a new LttType
312 ****************************************************************************/
313
314 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
315 {
316 LttType * lttType = NULL;
317 unsigned int i=0;
318 gchar * name;
319
320 if(td->type_name){
321 for(i=0;i<fac->named_types_number; i++){
322 if(fac->named_types[i] == NULL) break;
323 name = fac->named_types[i]->type_name;
324 if(g_ascii_strcasecmp(name, td->type_name)==0){
325 lttType = fac->named_types[i];
326 // if(lttType->element_name) g_free(lttType->element_name);
327 // lttType->element_name = NULL;
328 break;
329 }
330 }
331 }
332
333 if(!lttType){
334 lttType = g_new(LttType,1);
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;
342 lttType->element_name = NULL;
343 if(td->type_name){
344 lttType->type_name = g_strdup(td->type_name);
345 fac->named_types[i] = lttType; /* i is initialized, checked. */
346 }
347 else{
348 lttType->type_name = NULL;
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
366 int ltt_facility_close(LttFacility *f)
367 {
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
378 void freeFacility(LttFacility * fac)
379 {
380 unsigned int i;
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 }
387 g_free(fac->events);
388
389 //free all named types
390 for(i=0;i<fac->named_types_number;i++){
391 freeLttNamedType(fac->named_types[i]);
392 fac->named_types[i] = NULL;
393 }
394 g_free(fac->named_types);
395
396 //free the facility itself
397 g_free(fac);
398 }
399
400 void freeEventtype(LttEventType * evType)
401 {
402 LttType * root_type;
403 g_free(evType->name);
404 if(evType->description)
405 g_free(evType->description);
406 if(evType->root_field){
407 root_type = evType->root_field->field_type;
408 freeLttField(evType->root_field);
409 freeLttType(&root_type);
410 }
411
412 g_free(evType);
413 }
414
415 void freeLttNamedType(LttType * type)
416 {
417 g_free(type->type_name);
418 type->type_name = NULL;
419 freeLttType(&type);
420 }
421
422 void freeLttType(LttType ** type)
423 {
424 unsigned int i;
425 if(*type == NULL) return;
426 if((*type)->type_name){
427 return; //this is a named type
428 }
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);
437 }
438
439 if((*type)->element_type){
440 for(i=0;i<(*type)->element_number;i++)
441 freeLttType(&((*type)->element_type[i]));
442 g_free((*type)->element_type);
443 }
444 g_free(*type);
445 *type = NULL;
446 }
447
448 void freeLttField(LttField * fld)
449 {
450 int i;
451 int size = 0;
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 }
460 }
461
462 if(fld->child){
463 for(i=0; i<size; i++){
464 if(fld->child[i])freeLttField(fld->child[i]);
465 }
466 g_free(fld->child);
467 }
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
480 gchar *ltt_facility_name(LttFacility *f)
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
491 * LttChecksum : the checksum of the facility
492 ****************************************************************************/
493
494 LttChecksum ltt_facility_checksum(LttFacility *f)
495 {
496 return f->checksum;
497 }
498
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
508 unsigned ltt_facility_base_id(LttFacility *f)
509 {
510 return f->base_id;
511 }
512
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
522 unsigned ltt_facility_eventtype_number(LttFacility *f)
523 {
524 return (f->event_number);
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
534 * LttEventType * : the event type required
535 ****************************************************************************/
536
537 LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
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
548 * f : the facility
549 * name : the name of the event
550 *Return value
551 * LttEventType * : the event type required
552 ****************************************************************************/
553
554 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, gchar *name)
555 {
556 unsigned int i;
557 LttEventType * ev = NULL;
558
559 for(i=0;i<f->event_number;i++){
560 LttEventType *iter_ev = f->events[i];
561 if(g_ascii_strcasecmp(iter_ev->name, name) == 0) {
562 ev = iter_ev;
563 break;
564 }
565 }
566 return ev;
567 }
568
This page took 0.047788 seconds and 4 git commands to generate.