2 /* This file is part of the Linux Trace Toolkit viewer
3 * Copyright (C) 2003-2004 Xiangxiu Yang
4 * 2005 Mathieu Desnoyers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License Version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
29 #include <sys/types.h>
37 #include "ltt-private.h"
38 #include <ltt/facility.h>
46 /* search for the (named) type in the table, if it does not exist
48 LttType
* lookup_named_type(LttFacility
*fac
, type_descriptor_t
* td
);
50 /* construct directed acyclic graph for types, and tree for fields */
51 void construct_fields(LttFacility
*fac
,
55 /* generate the facility according to the events belongin to it */
56 void generateFacility(LttFacility
* f
, facility_t
* fac
,
59 /* functions to release the memory occupied by a facility */
60 void freeFacility(LttFacility
* facility
);
61 void freeEventtype(LttEventType
* evType
);
62 void freeLttType(LttType
* type
);
63 void freeLttField(LttField
* fld
);
64 void freeLttNamedType(LttType
* type
);
67 /*****************************************************************************
69 * parse_fmt : parses the format string
71 * fmt : format string specified in the xml file
72 * header : points to the extracted header string
73 * separator : points to the extracted separator string
74 * footer : points to the extracted footer string
76 * Parses the format string in order to extract the header,
77 * the separator and the footer.
78 * The default fmt string is: { %S, %S }
84 ****************************************************************************/
86 parse_fmt(char *fmt
, char **header
, char **separator
, char **footer
){
90 int header_index
= 0;//header index
91 int separator_index
= 0;//separator index
92 int footer_index
= 0;//footer index
93 int fmt_length
= strlen(fmt
);
95 for(i
=0; i
<fmt_length
; i
++)
101 g_error("More than 2 '%%' chars were encountered: %s\n",fmt
);
103 //Detecting identifier
105 g_error("Unexpected format: %s\n",fmt
);
110 g_error("Unexpected format: %s\n",fmt
);
112 //Need to have at least on char after the %S
114 g_error("Missing separator: %s\n",fmt
);
116 if(separator_index
==0)
117 separator_index
= i
;//index of separator inside the original string.
118 else if(footer_index
==0)//the 'else' gives the priority to set the separator index first.
119 footer_index
= i
;//no break since an error should be generated if more than 2 '%' were encountered
124 //Create header String
125 num
= separator_index
-header_index
-2;//(-2 due to '%S')
127 g_error("Unexpected format");
128 //*header = malloc(num+1);//(+1 for EOS).
129 *header
= g_new(gchar
,num
+1);//(+1 for EOS).
130 strncpy(*header
,fmt
,num
);
131 (*header
)[num
] = '\0';//need EOS, not handled by strncopy
133 //Create seperator String
134 num
=footer_index
- separator_index
- 2;
136 g_error("Unexpected format");
137 //*separator = malloc(num+1);//+1 for EOS
138 *separator
= g_new(gchar
, num
+1);//+1 for EOS
139 strncpy(*separator
,fmt
+separator_index
*sizeof(char),num
);
140 (*separator
)[num
] = '\0';//need EOS, not handled by strncopy
142 //Create footer String
143 num
= strlen(fmt
)-footer_index
;
144 //*footer = malloc(num+1);
145 *footer
= g_new(gchar
, num
+1);
146 strncpy(*footer
,fmt
+footer_index
*sizeof(char),num
);
147 (*footer
)[num
] = '\0';
150 /*****************************************************************************
152 * verify_fmt_syntax : verifies the syntax of the format string
154 * fmt : format string specified in the xml file
155 * fmt_type : points to the detected type in the fmt string
157 * Verifies the syntax of the format string sepcified in the xml file
158 * It allows fmt strings having the following syntax:
159 * "..header text... %12.20d ...footer text..."
160 * It sets the fmt_type accordingly. In the previous example
161 * fmt_type would point to the character 'd' inside fmt.
163 *returns 1 on success, and -1 or -2 on error.
165 ****************************************************************************/
167 int verify_fmt_syntax(char *fmt
, char **fmt_type
){
169 int dot
= 0;//number of dots encountered.
170 unsigned short counter
= 0;
174 for(i
=0; i
<strlen(fmt
); i
++)
179 return -1;//should generate an error.
181 i
= i
+1;//go to next character
183 if(fmt
[i
]=='-' && i
<(strlen(fmt
)-1))
184 i
++;//allow this character after the '%'
186 if(fmt
[i
]=='#' && i
<(strlen(fmt
)-1))
187 i
++;//allow this character
190 if(counter
==1 && !isdigit(fmt
[i
]) && *fmt_type
==NULL
)
205 //do not return yet. may encounter another '%'
208 return -2;//generate error
220 /*****************************************************************************
222 * append_ll : appends "ll" to the format string
224 * fmt : format string specified in the xml file
225 * fmt_type : address of the format char inside fmt
227 * inserts "ll" just before the fmt_type
229 ****************************************************************************/
231 void append_ll (char **fmt
, char **fmt_type
){
237 //the +2 corresponds the the "ll"; the +1 is the \0
238 new_fmt
= g_new(gchar
, strlen(*fmt
)+2+1);
240 num
= *fmt_type
- *fmt
;
243 new_fmt
[i
] =(*fmt
)[i
];
249 while(i
-2<strlen(*fmt
))
251 new_fmt
[i
]=(*fmt
)[i
-2];
261 /*****************************************************************************
263 * ltt_facility_open : open facilities
265 * t : the trace containing the facilities
266 * pathname : the path name of the facility
268 * Open the facility corresponding to the right checksum.
270 *returns 0 on success, 1 on error.
271 ****************************************************************************/
273 int ltt_facility_open(LttFacility
*f
, LttTrace
* t
, gchar
* pathname
)
279 unsigned int checksum
;
280 gchar buffer
[BUFFER_SIZE
];
281 gboolean generated
= FALSE
;
283 in
.buffer
= &(buffer
[0]);
285 in
.error
= error_callback
;
289 in
.fp
= fopen(in
.name
, "r");
291 g_warning("cannot open facility description file %s",
298 token
= getToken(&in
);
299 if(in
.type
== ENDFILE
) break;
301 if(g_ascii_strcasecmp(token
, "<")) in
.error(&in
,"not a facility file");
302 token
= getName(&in
);
303 if(g_ascii_strcasecmp(token
, "?")) in
.error(&in
,"not a facility file");
304 token
= getName(&in
);
305 if(g_ascii_strcasecmp(token
, "xml")) in
.error(&in
,"not a facility file");
306 token
= getName(&in
);
307 if(g_ascii_strcasecmp(token
, "version")) in
.error(&in
,"not a facility file");
308 token
= getName(&in
);
309 if(g_ascii_strcasecmp(token
, "=")) in
.error(&in
,"not a facility file");
310 token
= getQuotedString(&in
);
311 if(g_ascii_strcasecmp(token
, "1.0")) in
.error(&in
,"not a facility file");
312 token
= getName(&in
);
313 if(g_ascii_strcasecmp(token
, "?")) in
.error(&in
,"not a facility file");
314 token
= getToken(&in
);
315 if(g_ascii_strcasecmp(token
, ">")) in
.error(&in
,"not a facility file");
317 token
= getToken(&in
);
319 if(g_ascii_strcasecmp(token
, "<")) in
.error(&in
,"not a facility file");
320 token
= getName(&in
);
322 if(g_ascii_strcasecmp("facility",token
) == 0) {
323 fac
= g_new(facility_t
, 1);
325 fac
->description
= NULL
;
326 sequence_init(&(fac
->events
));
327 table_init(&(fac
->named_types
));
328 sequence_init(&(fac
->unnamed_types
));
330 parseFacility(&in
, fac
);
332 //check if any namedType is not defined
333 checkNamedTypesImplemented(&fac
->named_types
);
335 generateChecksum(fac
->name
, &checksum
, &fac
->events
);
336 // FIXME if(checksum == f->checksum) {
337 generateFacility(f
, fac
, checksum
);
340 if (checksum
!= f
->checksum
)
341 g_warning("Facility checksum mismatch for facility %s : kernel 0x%X vs "
342 "XML 0x%X\n", fac
->name
, f
->checksum
, checksum
);
346 g_free(fac
->description
);
347 freeEvents(&fac
->events
);
348 sequence_dispose(&fac
->events
);
349 freeNamedType(&fac
->named_types
);
350 table_dispose(&fac
->named_types
);
351 freeTypes(&fac
->unnamed_types
);
352 sequence_dispose(&fac
->unnamed_types
);
354 if(generated
) break; /* use the first good match */
357 g_warning("facility token was expected in file %s", in
.name
);
368 g_warning("Cannot find facility %s, checksum 0x%X",
369 g_quark_to_string(f
->name
), f
->checksum
);
377 /*****************************************************************************
379 * generateFacility : generate facility, internal function
381 * facility : LttFacilty structure
382 * fac : facility structure
383 * checksum : checksum of the facility
384 ****************************************************************************/
386 void generateFacility(LttFacility
*f
, facility_t
*fac
, guint32 checksum
)
388 char * facilityName
= fac
->name
;
389 sequence_t
* events
= &fac
->events
;
392 table_t
*named_types
= &fac
->named_types
;
394 g_assert(f
->name
== g_quark_from_string(facilityName
));
395 //g_assert(f->checksum == checksum);
397 //f->event_number = events->position;
399 //initialize inner structures
400 f
->events
= g_array_sized_new (FALSE
, TRUE
, sizeof(LttEventType
),
402 //f->events = g_new(LttEventType*,f->event_number);
403 f
->events
= g_array_set_size(f
->events
, events
->position
);
405 g_datalist_init(&f
->events_by_name
);
406 // g_datalist_init(&f->named_types);
408 /* The first day, he created the named types */
410 for(i
=0; i
<named_types
->keys
.position
; i
++) {
411 GQuark name
= g_quark_from_string((char*)named_types
->keys
.array
[i
]);
412 type_descriptor_t
*td
= (type_descriptor_t
*)named_types
->values
.array
[i
];
414 /* Create the type */
415 type
= g_new(LttType
,1);
416 type
->type_name
= name
;
417 type
->type_class
= td
->type
;
418 if(td
->fmt
) type
->fmt
= g_strdup(td
->fmt
);
419 else type
->fmt
= NULL
;
420 type
->size
= td
->size
;
421 type
->enum_strings
= NULL
;
422 type
->element_type
= NULL
;
423 type
->element_number
= 0;
425 construct_types_and_fields(type
, td
, NULL
, NULL
, ...);
427 g_datalist_id_set_data_full(&fac
->named_types
, name
,
428 type
, (GDestroyNotify
)freeLttNamedType
);
432 /* The second day, he created the event fields and types */
433 //for each event, construct field and type acyclic graph
434 for(i
=0;i
<events
->position
;i
++){
435 event_t
*parser_event
= (event_t
*)events
->array
[i
];
436 LttEventType
*event_type
= &g_array_index(f
->events
, LttEventType
, i
);
439 g_quark_from_string(parser_event
->name
);
441 g_datalist_id_set_data(&f
->events_by_name
, event_type
->name
,
444 event_type
->description
=
445 g_strdup(parser_event
->description
);
447 event_type
->index
= i
;
448 event_type
->facility
= f
;
450 event_type
->has_compact_data
= parser_event
->compact_data
;
452 event_type
->fields
= g_array_sized_new(FALSE
, TRUE
,
453 sizeof(LttField
), parser_event
->fields
.position
);
455 g_array_set_size(event_type
->fields
, parser_event
->fields
.position
);
456 g_datalist_init(&event_type
->fields_by_name
);
458 for(j
=0; j
<parser_event
->fields
.position
; j
++) {
459 LttField
*field
= &g_array_index(event_type
->fields
, LttField
, j
);
460 field_t
*parser_field
= (field_t
*)parser_event
->fields
.array
[j
];
462 construct_fields(f
, field
, parser_field
);
463 g_datalist_id_set_data(&event_type
->fields_by_name
,
469 /* What about 2 days weeks ? */
473 /*****************************************************************************
475 * construct_types_and_fields : construct field tree and type graph,
476 * internal recursion function
478 * fac : facility struct
479 * field : destination lttv field
480 * fld : source parser field
481 ****************************************************************************/
484 //make the change for arrays and sequences
485 //no more root field. -> change this for an array of fields.
486 // Compute the field size here.
487 // Flag fields as "VARIABLE OFFSET" or "FIXED OFFSET" : as soon as
488 // a field with a variable size is found, all the following fields must
489 // be flagged with "VARIABLE OFFSET", this will be done by the offset
493 void construct_fields(LttFacility
*fac
,
497 char *fmt_type
;//gaby
499 type_descriptor_t
*td
;
503 field
->name
= g_quark_from_string(fld
->name
);
507 if(fld
->description
) {
508 len
= strlen(fld
->description
);
509 field
->description
= g_new(gchar
, len
+1);
510 strcpy(field
->description
, fld
->description
);
512 field
->dynamic_offsets
= NULL
;
513 type
= &field
->field_type
;
516 type
->enum_map
= NULL
;
518 type
->fields_by_name
= NULL
;
519 type
->network
= td
->network
;
523 type
->type_class
= LTT_INT_FIXED
;
524 type
->size
= td
->size
;
527 type
->type_class
= LTT_UINT_FIXED
;
528 type
->size
= td
->size
;
531 type
->type_class
= LTT_POINTER
;
532 type
->size
= fac
->pointer_size
;
535 type
->type_class
= LTT_CHAR
;
536 type
->size
= td
->size
;
539 type
->type_class
= LTT_UCHAR
;
540 type
->size
= td
->size
;
541 g_assert(type
->size
!= 0);
544 type
->type_class
= LTT_SHORT
;
545 type
->size
= td
->size
;
548 type
->type_class
= LTT_USHORT
;
549 type
->size
= td
->size
;
552 type
->type_class
= LTT_INT
;
553 type
->size
= fac
->int_size
;
556 type
->type_class
= LTT_UINT
;
557 type
->size
= fac
->int_size
;
558 g_assert(type
->size
!= 0);
561 type
->type_class
= LTT_LONG
;
562 type
->size
= fac
->long_size
;
565 type
->type_class
= LTT_ULONG
;
566 type
->size
= fac
->long_size
;
569 type
->type_class
= LTT_SIZE_T
;
570 type
->size
= fac
->size_t_size
;
573 type
->type_class
= LTT_SSIZE_T
;
574 type
->size
= fac
->size_t_size
;
577 type
->type_class
= LTT_OFF_T
;
578 type
->size
= fac
->size_t_size
;
581 type
->type_class
= LTT_FLOAT
;
582 type
->size
= td
->size
;
585 type
->type_class
= LTT_STRING
;
589 type
->type_class
= LTT_ENUM
;
590 type
->size
= fac
->int_size
;
593 type
->enum_map
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
594 type
->lowest_value
= G_MAXINT32
;
595 type
->highest_value
= G_MININT32
;
596 for(i
=0; i
<td
->labels
.position
; i
++) {
597 GQuark value
= g_quark_from_string((char*)td
->labels
.array
[i
]);
598 gint key
= *(int*)td
->labels_values
.array
[i
];
599 g_hash_table_insert(type
->enum_map
, (gpointer
)key
, (gpointer
)value
);
600 type
->highest_value
= max(key
, type
->highest_value
);
601 type
->lowest_value
= min(key
, type
->lowest_value
);
604 g_assert(type
->size
!= 0);
607 type
->type_class
= LTT_ARRAY
;
608 type
->size
= td
->size
;
609 type
->fields
= g_array_sized_new(FALSE
, TRUE
, sizeof(LttField
),
610 td
->fields
.position
);
611 type
->fields
= g_array_set_size(type
->fields
, td
->fields
.position
);
615 for(i
=0; i
<td
->fields
.position
; i
++) {
616 field_t
*schild
= (field_t
*)td
->fields
.array
[i
];
617 LttField
*dchild
= &g_array_index(type
->fields
, LttField
, i
);
619 construct_fields(fac
, dchild
, schild
);
624 type
->type_class
= LTT_SEQUENCE
;
626 type
->fields
= g_array_sized_new(FALSE
, TRUE
, sizeof(LttField
),
627 td
->fields
.position
);
628 type
->fields
= g_array_set_size(type
->fields
, td
->fields
.position
);
632 for(i
=0; i
<td
->fields
.position
; i
++) {
633 field_t
*schild
= (field_t
*)td
->fields
.array
[i
];
634 LttField
*dchild
= &g_array_index(type
->fields
, LttField
, i
);
636 construct_fields(fac
, dchild
, schild
);
641 type
->type_class
= LTT_STRUCT
;
642 type
->size
= 0; // Size not calculated by the parser.
643 type
->fields
= g_array_sized_new(FALSE
, TRUE
, sizeof(LttField
),
644 td
->fields
.position
);
645 type
->fields
= g_array_set_size(type
->fields
, td
->fields
.position
);
646 g_datalist_init(&type
->fields_by_name
);
650 for(i
=0; i
<td
->fields
.position
; i
++) {
651 field_t
*schild
= (field_t
*)td
->fields
.array
[i
];
652 LttField
*dchild
= &g_array_index(type
->fields
, LttField
, i
);
654 construct_fields(fac
, dchild
, schild
);
655 g_datalist_id_set_data(&type
->fields_by_name
,
662 type
->type_class
= LTT_UNION
;
663 type
->size
= 0; // Size not calculated by the parser.
664 type
->fields
= g_array_sized_new(FALSE
, TRUE
, sizeof(LttField
),
665 td
->fields
.position
);
666 type
->fields
= g_array_set_size(type
->fields
, td
->fields
.position
);
667 g_datalist_init(&type
->fields_by_name
);
671 for(i
=0; i
<td
->fields
.position
; i
++) {
672 field_t
*schild
= (field_t
*)td
->fields
.array
[i
];
673 LttField
*dchild
= &g_array_index(type
->fields
, LttField
, i
);
675 construct_fields(fac
, dchild
, schild
);
676 g_datalist_id_set_data(&type
->fields_by_name
,
684 g_error("construct_fields : unknown type");
687 field
->field_size
= type
->size
;
689 /* Put the fields as "variable" offset to root first. Then,
690 * the offset precomputation will only have to set the FIELD_FIXED until
691 * it reaches the first variable length field, then stop.
693 field
->fixed_root
= FIELD_VARIABLE
;
696 len
= strlen(td
->fmt
);
697 type
->fmt
= g_new(gchar
, len
+1);
698 strcpy(type
->fmt
, td
->fmt
);
700 //here I should verify syntax based on type.
701 //if type is array or sequence or enum, parse_fmt.
702 //if type is basic, verify syntax, and allow or not the type format.
703 //the code can be integrated in the above code (after testing)
707 switch (type
->type_class
){
714 //Assign a default format for these complex types
715 //type->fmt = malloc(11*sizeof(char));
716 type
->fmt
= g_new(gchar
, 11);
717 type
->fmt
= g_strdup("{ %S, %S }");//set a default value for fmt. can directly set header and footer, but kept this way on purpose.
719 //Parse the fmt string in order to extract header, separator and footer
720 parse_fmt(type
->fmt
,&(type
->header
),&(type
->separator
),&(type
->footer
));
729 if(type
->fmt
== NULL
)
731 //Assign a default format string
732 //type->fmt = malloc(5*sizeof(char));
733 type
->fmt
= g_new(gchar
, 5);
734 type
->fmt
=g_strdup("%lld");
738 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>0)
744 append_ll(&(type
->fmt
),&fmt_type
);//append 'll' to fmt
747 g_error("Format type '%c' not supported\n",fmt_type
[0]);
758 if(type
->fmt
== NULL
)
760 //Assign a default format string
761 //type->fmt= malloc(5*sizeof(char));
762 type
->fmt
= g_new(gchar
, 5);
763 type
->fmt
=g_strdup("%lld");
767 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>0)
774 append_ll(&(type
->fmt
),&fmt_type
);
777 g_error("Format type '%c' not supported\n",fmt_type
[0]);
783 if(type
->fmt
== NULL
)
785 //Assign a default format string
786 //type->fmt = malloc(3*sizeof(char));
787 type
->fmt
= g_new(gchar
, 3);
788 type
->fmt
= g_strdup("%c");
792 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>1)
802 g_error("Format type '%c' not supported\n",fmt_type
[0]);
807 if(type
->fmt
== NULL
)
809 //Assign a default format string
810 //type->fmt = malloc(3*sizeof(char));
811 type
->fmt
= g_new(gchar
, 3);
812 type
->fmt
= g_strdup("%g");
816 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>0)
825 g_error("Format type '%c' not supported\n",fmt_type
[0]);
830 if(type
->fmt
== NULL
)
832 //Assign a default format string
833 //type->fmt = malloc(7*sizeof(char));
834 type
->fmt
= g_new(gchar
, 7);
835 type
->fmt
= g_strdup("0x%llx");
839 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>0)
842 //type->fmt = malloc(7*sizeof(char));
843 type
->fmt
= g_new(gchar
, 7);
844 type
->fmt
= g_strdup("0x%llx");
849 append_ll(&(type
->fmt
),&fmt_type
);
852 g_error("Format type '%c' not supported\n",fmt_type
[0]);
857 if(type
->fmt
== NULL
)
859 //type->fmt = malloc(7*sizeof(char));
860 type
->fmt
= g_new(gchar
, 5);
861 type
->fmt
= g_strdup("\"%s\"");//default value for fmt.
865 if(verify_fmt_syntax((type
->fmt
),&fmt_type
)>0)
870 g_error("Format type '%c' not supported\n", fmt_type
[0]);
883 void construct_types_and_fields(LttFacility
* fac
, type_descriptor_t
* td
,
887 type_descriptor_t
* tmpTd
;
893 fld
->field_type
->size
= td
->size
;
901 fld
->field_type
->size
= 0;
904 fld
->field_type
->size
= 0;
907 fld
->field_type
->element_number
= td
->labels
.position
;
908 fld
->field_type
->enum_strings
= g_new(GQuark
,td
->labels
.position
);
909 for(i
=0;i
<td
->labels
.position
;i
++){
910 fld
->field_type
->enum_strings
[i
]
911 = g_quark_from_string(((char*)(td
->labels
.array
[i
])));
913 fld
->field_type
->size
= td
->size
;
917 fld
->field_type
->element_number
= (unsigned)td
->size
;
919 fld
->field_type
->element_type
= g_new(LttType
*,1);
920 tmpTd
= td
->nested_type
;
921 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
922 fld
->child
= g_new(LttField
*, 1);
923 fld
->child
[0] = g_new(LttField
, 1);
925 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
926 fld
->child
[0]->offset_root
= 0;
927 fld
->child
[0]->fixed_root
= FIELD_UNKNOWN
;
928 fld
->child
[0]->offset_parent
= 0;
929 fld
->child
[0]->fixed_parent
= FIELD_UNKNOWN
;
930 fld
->child
[0]->field_size
= 0;
931 fld
->child
[0]->fixed_size
= FIELD_UNKNOWN
;
932 fld
->child
[0]->parent
= fld
;
933 fld
->child
[0]->child
= NULL
;
934 fld
->child
[0]->current_element
= 0;
935 construct_types_and_fields(fac
, tmpTd
, fld
->child
[0]);
940 fld
->field_type
->element_number
= td
->fields
.position
;
942 g_assert(fld
->field_type
->element_type
== NULL
);
943 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
945 fld
->child
= g_new(LttField
*, td
->fields
.position
);
946 for(i
=0;i
<td
->fields
.position
;i
++){
947 tmpTd
= ((field_t
*)(td
->fields
.array
[i
]))->type
;
949 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
950 fld
->child
[i
] = g_new(LttField
,1);
952 // fld->child[i]->field_pos = i;
953 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
955 fld
->child
[i
]->field_type
->element_name
956 = g_quark_from_string(((field_t
*)(td
->fields
.array
[i
]))->name
);
958 fld
->child
[i
]->offset_root
= 0;
959 fld
->child
[i
]->fixed_root
= FIELD_UNKNOWN
;
960 fld
->child
[i
]->offset_parent
= 0;
961 fld
->child
[i
]->fixed_parent
= FIELD_UNKNOWN
;
962 fld
->child
[i
]->field_size
= 0;
963 fld
->child
[i
]->fixed_size
= FIELD_UNKNOWN
;
964 fld
->child
[i
]->parent
= fld
;
965 fld
->child
[i
]->child
= NULL
;
966 fld
->child
[i
]->current_element
= 0;
967 construct_types_and_fields(fac
, tmpTd
, fld
->child
[i
]);
972 g_error("construct_types_and_fields : unknown type");
981 void construct_types_and_fields(LttFacility
* fac
, type_descriptor
* td
,
985 type_descriptor
* tmpTd
;
987 // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
988 // fld->field_size = 0;
989 // else fld->field_size = -1;
991 if(td
->type
== LTT_ENUM
){
992 fld
->field_type
->element_number
= td
->labels
.position
;
993 fld
->field_type
->enum_strings
= g_new(GQuark
,td
->labels
.position
);
994 for(i
=0;i
<td
->labels
.position
;i
++){
995 fld
->field_type
->enum_strings
[i
]
996 = g_quark_from_string(((char*)(td
->labels
.array
[i
])));
998 }else if(td
->type
== LTT_ARRAY
|| td
->type
== LTT_SEQUENCE
){
999 if(td
->type
== LTT_ARRAY
)
1000 fld
->field_type
->element_number
= (unsigned)td
->size
;
1001 fld
->field_type
->element_type
= g_new(LttType
*,1);
1002 tmpTd
= td
->nested_type
;
1003 fld
->field_type
->element_type
[0] = lookup_named_type(fac
, tmpTd
);
1004 fld
->child
= g_new(LttField
*, 1);
1005 fld
->child
[0] = g_new(LttField
, 1);
1007 // fld->child[0]->field_pos = 0;
1008 fld
->child
[0]->field_type
= fld
->field_type
->element_type
[0];
1009 fld
->child
[0]->offset_root
= fld
->offset_root
;
1010 fld
->child
[0]->fixed_root
= fld
->fixed_root
;
1011 fld
->child
[0]->offset_parent
= 0;
1012 fld
->child
[0]->fixed_parent
= 1;
1013 // fld->child[0]->base_address = NULL;
1014 fld
->child
[0]->field_size
= 0;
1015 fld
->child
[0]->field_fixed
= -1;
1016 fld
->child
[0]->parent
= fld
;
1017 fld
->child
[0]->child
= NULL
;
1018 fld
->child
[0]->current_element
= 0;
1019 construct_types_and_fields(fac
, tmpTd
, fld
->child
[0]);
1020 }else if(td
->type
== LTT_STRUCT
){
1021 fld
->field_type
->element_number
= td
->fields
.position
;
1023 if(fld
->field_type
->element_type
== NULL
){
1024 fld
->field_type
->element_type
= g_new(LttType
*, td
->fields
.position
);
1030 fld
->child
= g_new(LttField
*, td
->fields
.position
);
1031 for(i
=0;i
<td
->fields
.position
;i
++){
1032 tmpTd
= ((type_fields
*)(td
->fields
.array
[i
]))->type
;
1035 fld
->field_type
->element_type
[i
] = lookup_named_type(fac
, tmpTd
);
1036 fld
->child
[i
] = g_new(LttField
,1);
1038 fld
->child
[i
]->field_pos
= i
;
1039 fld
->child
[i
]->field_type
= fld
->field_type
->element_type
[i
];
1042 fld
->child
[i
]->field_type
->element_name
1043 = g_quark_from_string(((type_fields
*)(td
->fields
.array
[i
]))->name
);
1046 fld
->child
[i
]->offset_root
= -1;
1047 fld
->child
[i
]->fixed_root
= -1;
1048 fld
->child
[i
]->offset_parent
= -1;
1049 fld
->child
[i
]->fixed_parent
= -1;
1050 // fld->child[i]->base_address = NULL;
1051 fld
->child
[i
]->field_size
= 0;
1052 fld
->child
[i
]->field_fixed
= -1;
1053 fld
->child
[i
]->parent
= fld
;
1054 fld
->child
[i
]->child
= NULL
;
1055 fld
->child
[i
]->current_element
= 0;
1056 construct_types_and_fields(fac
, tmpTd
, fld
->child
[i
]);
1063 /*****************************************************************************
1065 * lookup_named_type: search named type in the table
1068 * fac : facility struct
1071 * : either find the named type, or create a new LttType
1072 ****************************************************************************/
1074 LttType
* lookup_named_type(LttFacility
*fac
, GQuark type_name
)
1076 LttType
*type
= NULL
;
1079 type
= g_datalist_id_get_data(&fac
->named_types
, name
);
1081 g_assert(type
!= NULL
);
1084 /* Create the type */
1085 type
= g_new(LttType
,1);
1086 type
->type_name
= name
;
1087 type
->type_class
= td
->type
;
1088 if(td
->fmt
) type
->fmt
= g_strdup(td
->fmt
);
1089 else type
->fmt
= NULL
;
1090 type
->size
= td
->size
;
1091 type
->enum_strings
= NULL
;
1092 type
->element_type
= NULL
;
1093 type
->element_number
= 0;
1095 if(td
->type_name
!= NULL
)
1096 g_datalist_id_set_data_full(&fac
->named_types
, name
,
1097 type
, (GDestroyNotify
)freeLttNamedType
);
1104 /*****************************************************************************
1106 * ltt_facility_close : close a facility, decrease its usage count,
1107 * if usage count = 0, release the memory
1109 * f : facility that will be closed
1110 ****************************************************************************/
1112 void ltt_facility_close(LttFacility
*f
)
1114 //release the memory it occupied
1118 /*****************************************************************************
1119 * Functions to release the memory occupied by the facility
1120 ****************************************************************************/
1122 void freeFacility(LttFacility
* fac
)
1127 for(i
=0; i
<fac
->events
->len
; i
++) {
1128 et
= &g_array_index (fac
->events
, LttEventType
, i
);
1131 g_array_free(fac
->events
, TRUE
);
1133 g_datalist_clear(&fac
->events_by_name
);
1135 // g_datalist_clear(&fac->named_types);
1138 void freeEventtype(LttEventType
* evType
)
1141 LttType
* root_type
;
1142 if(evType
->description
)
1143 g_free(evType
->description
);
1145 for(i
=0; i
<evType
->fields
->len
;i
++) {
1146 LttField
*field
= &g_array_index(evType
->fields
, LttField
, i
);
1147 freeLttField(field
);
1149 g_array_free(evType
->fields
, TRUE
);
1150 g_datalist_clear(&evType
->fields_by_name
);
1153 void freeLttType(LttType
* type
)
1161 g_hash_table_destroy(type
->enum_map
);
1164 for(i
=0; i
<type
->fields
->len
; i
++) {
1165 freeLttField(&g_array_index(type
->fields
, LttField
, i
));
1167 g_array_free(type
->fields
, TRUE
);
1169 if(type
->fields_by_name
)
1170 g_datalist_clear(&type
->fields_by_name
);
1173 g_free(type
->header
);//no need for condition? if(type->header)
1175 g_free(type
->separator
);
1177 g_free(type
->footer
);
1180 void freeLttNamedType(LttType
* type
)
1185 void freeLttField(LttField
* field
)
1187 if(field
->description
)
1188 g_free(field
->description
);
1189 if(field
->dynamic_offsets
)
1190 g_array_free(field
->dynamic_offsets
, TRUE
);
1191 freeLttType(&field
->field_type
);
1194 /*****************************************************************************
1196 * ltt_facility_name : obtain the facility's name
1200 * GQuark : the facility's name
1201 ****************************************************************************/
1203 GQuark
ltt_facility_name(LttFacility
*f
)
1208 /*****************************************************************************
1210 * ltt_facility_checksum : obtain the facility's checksum
1214 * : the checksum of the facility
1215 ****************************************************************************/
1217 guint32
ltt_facility_checksum(LttFacility
*f
)
1222 /*****************************************************************************
1224 * ltt_facility_base_id : obtain the facility base id
1228 * : the base id of the facility
1229 ****************************************************************************/
1231 guint
ltt_facility_id(LttFacility
*f
)
1236 /*****************************************************************************
1238 * ltt_facility_eventtype_number: obtain the number of the event types
1240 * f : the facility that will be closed
1242 * : the number of the event types
1243 ****************************************************************************/
1245 guint8
ltt_facility_eventtype_number(LttFacility
*f
)
1247 return (f
->events
->len
);
1250 /*****************************************************************************
1252 * ltt_facility_eventtype_get: obtain the event type according to event id
1253 * from 0 to event_number - 1
1255 * f : the facility that will be closed
1257 * LttEventType * : the event type required
1258 ****************************************************************************/
1260 LttEventType
*ltt_facility_eventtype_get(LttFacility
*f
, guint8 i
)
1262 if(!f
->exists
) return NULL
;
1264 g_assert(i
< f
->events
->len
);
1265 return &g_array_index(f
->events
, LttEventType
, i
);
1268 /*****************************************************************************
1270 * ltt_facility_eventtype_get_by_name
1271 * : obtain the event type according to event name
1272 * event name is unique in the facility
1275 * name : the name of the event
1277 * LttEventType * : the event type required
1278 ****************************************************************************/
1280 LttEventType
*ltt_facility_eventtype_get_by_name(LttFacility
*f
, GQuark name
)
1282 LttEventType
*et
= g_datalist_id_get_data(&f
->events_by_name
, name
);
This page took 0.122018 seconds and 4 git commands to generate.