UTF8 fix
[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/gstdio.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 #define g_close close
35
36 /* search for the (named) type in the table, if it does not exist
37 create a new one */
38 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td);
39
40 /* construct directed acyclic graph for types, and tree for fields */
41 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
42 LttField * fld);
43
44 /* generate the facility according to the events belongin to it */
45 void generateFacility(LttFacility * f, facility_t * fac,
46 LttChecksum checksum);
47
48 /* functions to release the memory occupied by a facility */
49 void freeFacility(LttFacility * facility);
50 void freeEventtype(LttEventType * evType);
51 void freeLttType(LttType ** type);
52 void freeLttField(LttField * fld);
53 void freeLttNamedType(LttType * type);
54
55
56 /*****************************************************************************
57 *Function name
58 * ltt_facility_open : open facilities
59 *Input params
60 * t : the trace containing the facilities
61 * pathname : the path name of the facility
62 ****************************************************************************/
63
64 void ltt_facility_open(LttTrace * t, gchar * pathname)
65 {
66 gchar *token;
67 parse_file in;
68 gsize length;
69 facility_t * fac;
70 LttFacility * f;
71 LttChecksum checksum;
72 GError * error = NULL;
73 gchar buffer[BUFFER_SIZE];
74
75 in.buffer = &(buffer[0]);
76 in.lineno = 0;
77 in.error = error_callback;
78 in.name = pathname;
79
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;
85
86 while(1){
87 token = getToken(&in);
88 if(in.type == ENDFILE) break;
89
90 if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
91 token = getName(&in);
92
93 if(g_ascii_strcasecmp("facility",token) == 0) {
94 fac = g_new(facility_t, 1);
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
104 g_assert(checkNamedTypesImplemented(&fac->named_types) == 0);
105
106 g_assert(generateChecksum(fac->name, &checksum, &fac->events) == 0);
107
108 f = g_new(LttFacility,1);
109 f->base_id = 0;
110 generateFacility(f, fac, checksum);
111
112 t->facility_number++;
113 g_ptr_array_add(t->facilities,f);
114
115 g_free(fac->name);
116 g_free(fac->description);
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);
123 g_free(fac);
124 }
125 else in.error(&in,"facility token was expected");
126 }
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);
135 }
136
137
138 /*****************************************************************************
139 *Function name
140 * generateFacility : generate facility, internal function
141 *Input params
142 * facility : LttFacilty structure
143 * fac : facility structure
144 * checksum : checksum of the facility
145 ****************************************************************************/
146
147 void generateFacility(LttFacility *f, facility_t *fac,LttChecksum checksum)
148 {
149 char * facilityName = fac->name;
150 sequence * events = &fac->events;
151 int i;
152 LttEventType * evType;
153 LttField * field;
154 LttType * type;
155
156 f->name = g_strdup(facilityName);
157 f->event_number = events->position;
158 f->checksum = checksum;
159
160 //initialize inner structures
161 f->events = g_new(LttEventType*,f->event_number);
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;
165
166 //for each event, construct field tree and type graph
167 for(i=0;i<events->position;i++){
168 evType = g_new(LttEventType,1);
169 f->events[i] = evType;
170
171 evType->name = g_strdup(((event_t*)(events->array[i]))->name);
172 evType->description=g_strdup(((event_t*)(events->array[i]))->description);
173
174 field = g_new(LttField, 1);
175 evType->root_field = field;
176 evType->facility = f;
177 evType->index = i;
178
179 if(((event_t*)(events->array[i]))->type != NULL){
180 field->field_pos = 0;
181 type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
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;
193
194 //construct field tree and type graph
195 constructTypeAndFields(f,((event_t*)(events->array[i]))->type,field);
196 }else{
197 evType->root_field = NULL;
198 g_free(field);
199 }
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
214 void constructTypeAndFields(LttFacility * fac,type_descriptor * td,
215 LttField * fld)
216 {
217 int i, flag;
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;
234 fld->field_type->element_type = g_new(LttType*,1);
235 tmpTd = td->nested_type;
236 fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
237 fld->child = g_new(LttField*, 1);
238 fld->child[0] = g_new(LttField, 1);
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;
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
263 fld->child = g_new(LttField*, td->fields.position);
264 for(i=0;i<td->fields.position;i++){
265 tmpTd = ((type_fields*)(td->fields.array[i]))->type;
266
267 if(flag)
268 fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
269 fld->child[i] = g_new(LttField,1);
270
271 fld->child[i]->field_pos = i;
272 fld->child[i]->field_type = fld->field_type->element_type[i];
273
274 if(flag){
275 fld->child[i]->field_type->element_name
276 = g_strdup(((type_fields*)(td->fields.array[i]))->name);
277 }
278
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
303 * : either find the named type, or create a new LttType
304 ****************************************************************************/
305
306 LttType * lookup_named_type(LttFacility *fac, type_descriptor * td)
307 {
308 LttType * lttType = NULL;
309 unsigned int i=0;
310 gchar * name;
311
312 if(td->type_name){
313 for(i=0;i<fac->named_types_number; i++){
314 if(fac->named_types[i] == NULL) break;
315 name = fac->named_types[i]->type_name;
316 if(g_ascii_strcasecmp(name, td->type_name)==0){
317 lttType = fac->named_types[i];
318 // if(lttType->element_name) g_free(lttType->element_name);
319 // lttType->element_name = NULL;
320 break;
321 }
322 }
323 }
324
325 if(!lttType){
326 lttType = g_new(LttType,1);
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;
334 lttType->element_name = NULL;
335 if(td->type_name){
336 lttType->type_name = g_strdup(td->type_name);
337 fac->named_types[i] = lttType; /* i is initialized, checked. */
338 }
339 else{
340 lttType->type_name = NULL;
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
358 int ltt_facility_close(LttFacility *f)
359 {
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
370 void freeFacility(LttFacility * fac)
371 {
372 unsigned int i;
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 }
379 g_free(fac->events);
380
381 //free all named types
382 for(i=0;i<fac->named_types_number;i++){
383 freeLttNamedType(fac->named_types[i]);
384 fac->named_types[i] = NULL;
385 }
386 g_free(fac->named_types);
387
388 //free the facility itself
389 g_free(fac);
390 }
391
392 void freeEventtype(LttEventType * evType)
393 {
394 LttType * root_type;
395 g_free(evType->name);
396 if(evType->description)
397 g_free(evType->description);
398 if(evType->root_field){
399 root_type = evType->root_field->field_type;
400 freeLttField(evType->root_field);
401 freeLttType(&root_type);
402 }
403
404 g_free(evType);
405 }
406
407 void freeLttNamedType(LttType * type)
408 {
409 g_free(type->type_name);
410 type->type_name = NULL;
411 freeLttType(&type);
412 }
413
414 void freeLttType(LttType ** type)
415 {
416 unsigned int i;
417 if(*type == NULL) return;
418 if((*type)->type_name){
419 return; //this is a named type
420 }
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);
429 }
430
431 if((*type)->element_type){
432 for(i=0;i<(*type)->element_number;i++)
433 freeLttType(&((*type)->element_type[i]));
434 g_free((*type)->element_type);
435 }
436 g_free(*type);
437 *type = NULL;
438 }
439
440 void freeLttField(LttField * fld)
441 {
442 int i;
443 int size = 0;
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 }
452 }
453
454 if(fld->child){
455 for(i=0; i<size; i++){
456 if(fld->child[i])freeLttField(fld->child[i]);
457 }
458 g_free(fld->child);
459 }
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
472 gchar *ltt_facility_name(LttFacility *f)
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
483 * LttChecksum : the checksum of the facility
484 ****************************************************************************/
485
486 LttChecksum ltt_facility_checksum(LttFacility *f)
487 {
488 return f->checksum;
489 }
490
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
500 unsigned ltt_facility_base_id(LttFacility *f)
501 {
502 return f->base_id;
503 }
504
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
514 unsigned ltt_facility_eventtype_number(LttFacility *f)
515 {
516 return (f->event_number);
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
526 * LttEventType * : the event type required
527 ****************************************************************************/
528
529 LttEventType *ltt_facility_eventtype_get(LttFacility *f, unsigned i)
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
540 * f : the facility
541 * name : the name of the event
542 *Return value
543 * LttEventType * : the event type required
544 ****************************************************************************/
545
546 LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, gchar *name)
547 {
548 unsigned int i;
549 LttEventType * ev = NULL;
550
551 for(i=0;i<f->event_number;i++){
552 LttEventType *iter_ev = f->events[i];
553 if(g_ascii_strcasecmp(iter_ev->name, name) == 0) {
554 ev = iter_ev;
555 break;
556 }
557 }
558 return ev;
559 }
560
This page took 0.041474 seconds and 4 git commands to generate.