6 parser.c: Generate helper declarations and functions to trace events
7 from an event description file.
9 Copyright (C) 2005, Mathieu Desnoyers
10 Copyright (C) 2002, Xianxiu Yang
11 Copyright (C) 2002, Michel Dagenais
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /* This program reads the ".xml" event definitions input files
27 and constructs structure for each event.
29 The program uses a very simple tokenizer, called from a hand written
30 recursive descent parser to fill a data structure describing the events.
31 The result is a sequence of events definitions which refer to type
34 A table of named types is maintained to allow refering to types by name
35 when the same type is used at several places. Finally a sequence of
36 all types is maintained to facilitate the freeing of all type
37 information when the processing of an ".xml" file is finished. */
43 #include <linux/errno.h>
50 char *intOutputTypes
[] = {
51 "int8_t", "int16_t", "int32_t", "int64_t" };
53 char *uintOutputTypes
[] = {
54 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
56 char *floatOutputTypes
[] = {
57 "undef", "undef", "float", "double" };
63 void strupper(char *string
)
74 int getSizeindex(unsigned int value
)
86 printf("Error : unknown value size %d\n", value
);
91 /*****************************************************************************
93 * getSize : translate from string to integer
95 * in : input file handle
98 *****************************************************************************/
100 unsigned long long int getSize(parse_file_t
*in
)
102 char *token
, *token2
;
103 unsigned long long int ret
;
105 token
= getToken(in
);
108 if(in
->type
== QUOTEDSTRING
) {
112 if (!isdigit(*token2
)) {
113 in
->type
= QUOTEDSTRING
;
116 } while (*(++token2
) != '\0');
119 if(in
->type
== NUMBER
) {
120 ret
= strtoull(token
, NULL
, 0);
127 in
->error(in
,"incorrect size specification");
131 /*****************************************************************************
133 * error_callback : print out error info
135 * in : input file handle
136 * msg : message to be printed
137 ****************************************************************************/
139 void error_callback(parse_file_t
*in
, char *msg
)
142 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
149 /*****************************************************************************
151 * memAlloc : allocate memory
153 * size : required memory size
155 * void * : pointer to allocate memory or NULL
156 ****************************************************************************/
158 void * memAlloc(int size
)
161 if(size
== 0) return NULL
;
164 printf("Failed to allocate memory");
170 /*****************************************************************************
172 * allocAndCopy : allocate memory and initialize it
174 * str : string to be put in memory
176 * char * : pointer to allocate memory or NULL
177 ****************************************************************************/
179 char *allocAndCopy(char *str
)
182 if(str
== NULL
) return NULL
;
183 addr
= (char *)memAlloc(strlen(str
)+1);
188 /**************************************************************************
192 * Read the attribute from the input file.
195 * in , input file handle.
196 * t , the type descriptor to fill.
198 **************************************************************************/
200 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
201 sequence_t
* unnamed_types
, table_t
* named_types
)
212 token
= getToken(in
);
213 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
218 if(!strcmp("format",token
)) {
220 t
->fmt
= allocAndCopy(getQuotedString(in
));
221 // printf("%s - ",t->fmt);
222 //} else if(!strcmp("name",token)) {
224 // car = seekNextChar(in);
225 // if(car == EOF) in->error(in,"name was expected");
226 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
227 // else t->type_name = allocAndCopy(getName(in));
228 } else if(!strcmp("size",token
)) {
230 t
->size
= getSize(in
);
231 } else if(!strcmp("custom_write", token
)) {
233 } else if(!strcmp("byte_order",token
)) {
235 car
= seekNextChar(in
);
236 if(car
== EOF
) in
->error(in
,"byte order was expected (network?)");
237 else if(car
== '\"') token
= getQuotedString(in
);
238 else token
= getName(in
);
239 if(!strcmp("network", token
)) {
242 } else if(!strcmp("write",token
)) {
244 car
= seekNextChar(in
);
245 if(car
== EOF
) in
->error(in
,"write type was expected (custom?)");
246 else if(car
== '\"') token
= getQuotedString(in
);
247 else token
= getName(in
);
248 if(!strcmp("custom", token
)) {
255 /**************************************************************************
259 * Read the attribute from the input file.
262 * in , input file handle.
263 * ev , the event to fill.
265 **************************************************************************/
267 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
274 ev
->per_tracefile
= 0;
275 ev
->param_buffer
= 0;
276 ev
->no_instrument_function
= 0;
277 ev
->high_priority
= 0;
279 ev
->compact_data
= 0;
282 token
= getToken(in
);
283 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
288 if(!strcmp("name",token
)) {
290 car
= seekNextChar(in
);
291 if(car
== EOF
) in
->error(in
,"name was expected");
292 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
293 else ev
->name
= allocAndCopy(getName(in
));
294 } else if(!strcmp("scope", token
)) {
296 car
= seekNextChar(in
);
297 if(car
== EOF
) in
->error(in
,"scope was expected");
298 else if(car
== '\"') token
= getQuotedString(in
);
299 else token
= getName(in
);
300 if(!strcmp(token
, "trace")) ev
->per_trace
= 1;
301 else if(!strcmp(token
, "tracefile")) ev
->per_tracefile
= 1;
302 } else if(!strcmp("param", token
)) {
304 car
= seekNextChar(in
);
305 if(car
== EOF
) in
->error(in
,"parameter type was expected");
306 else if(car
== '\"') token
= getQuotedString(in
);
307 else token
= getName(in
);
308 if(!strcmp(token
, "buffer")) ev
->param_buffer
= 1;
309 } else if(!strcmp("attribute", token
)) {
311 car
= seekNextChar(in
);
312 if(car
== EOF
) in
->error(in
,"attribute was expected");
313 else if(car
== '\"') token
= getQuotedString(in
);
314 else token
= getName(in
);
315 if(!strcmp(token
, "no_instrument_function"))
316 ev
->no_instrument_function
= 1;
317 else if(!strcmp(token
, "high_priority"))
318 ev
->high_priority
= 1;
319 else if(!strcmp(token
, "force"))
321 else if(!strcmp(token
, "compact_data"))
322 ev
->compact_data
= 1;
327 /**************************************************************************
329 * getFacilityAttributes
331 * Read the attribute from the input file.
334 * in , input file handle.
335 * fac , the facility to fill.
337 **************************************************************************/
339 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
350 token
= getToken(in
);
351 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
356 if(!strcmp("name",token
)) {
358 car
= seekNextChar(in
);
359 if(car
== EOF
) in
->error(in
,"name was expected");
360 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
361 else fac
->name
= allocAndCopy(getName(in
));
362 if(!strncmp(fac
->name
, "user_", sizeof("user_")-1))
364 } else if(!strcmp("arch", token
)) {
366 car
= seekNextChar(in
);
367 if(car
== '\"') fac
->arch
= allocAndCopy(getQuotedString(in
));
368 else fac
->arch
= allocAndCopy(getName(in
));
369 } else if(!strcmp("align", token
)) {
371 fac
->align
= getSize(in
);
377 /**************************************************************************
381 * Read the attribute from the input file.
384 * in , input file handle.
385 * f , the field to fill.
387 **************************************************************************/
389 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
397 token
= getToken(in
);
398 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
403 if(!strcmp("name",token
)) {
405 car
= seekNextChar(in
);
406 if(car
== EOF
) in
->error(in
,"name was expected");
407 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
408 else f
->name
= allocAndCopy(getName(in
));
413 char *getNameAttribute(parse_file_t
*in
)
420 token
= getToken(in
);
421 if(!strcmp("name",token
)) {
423 car
= seekNextChar(in
);
424 if(car
== EOF
) in
->error(in
,"name was expected");
425 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
426 else name
= allocAndCopy(getName(in
));
433 if(name
== NULL
) in
->error(in
, "Name was expected");
439 //for <label name=label_name value=n format="...">, value is an option
440 //Return value : 0 : no value, 1 : has a value
441 int getValueAttribute(parse_file_t
*in
, long long *value
)
443 char * token
, * endptr
;
445 token
= getToken(in
);
447 if(strcmp("/",token
) == 0 || strcmp(">", token
) == 0){
451 if(strcmp("value",token
))in
->error(in
,"value was expected");
454 token
= getToken(in
);
456 *value
= strtoll(token
, &endptr
, 0);
461 in
->error(in
,"invalid number specified");
465 char * getDescription(parse_file_t
*in
)
473 getLAnglebracket(in
);
475 if(strcmp("description",token
)){
476 fseek(in
->fp
, pos
, SEEK_SET
);
480 getRAnglebracket(in
);
483 while((car
= getc(in
->fp
)) != EOF
) {
484 if(car
== '<') break;
485 if(car
== '\0') continue;
486 in
->buffer
[pos
] = car
;
489 if(car
== EOF
)in
->error(in
,"not a valid description");
490 in
->buffer
[pos
] = '\0';
492 str
= allocAndCopy(in
->buffer
);
496 if(strcmp("description", token
))in
->error(in
,"not a valid description");
497 getRAnglebracket(in
);
502 /*****************************************************************************
504 * parseFacility : generate event list
506 * in : input file handle
507 * fac : empty facility
509 * fac : facility filled with event list
510 ****************************************************************************/
512 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
517 getFacilityAttributes(in
, fac
);
518 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
520 fac
->capname
= allocAndCopy(fac
->name
);
521 strupper(fac
->capname
);
522 getRAnglebracket(in
);
524 fac
->description
= getDescription(in
);
527 getLAnglebracket(in
);
529 token
= getToken(in
);
530 if(in
->type
== ENDFILE
)
531 in
->error(in
,"the definition of the facility is not finished");
533 if(strcmp("event",token
) == 0){
534 ev
= (event_t
*) memAlloc(sizeof(event_t
));
535 sequence_push(&(fac
->events
),ev
);
536 parseEvent(fac
, in
, ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
537 }else if(strcmp("type",token
) == 0){
538 parseTypeDefinition(fac
, in
, &(fac
->unnamed_types
), &(fac
->named_types
));
539 }else if(in
->type
== FORWARDSLASH
){
541 }else in
->error(in
,"event or type token expected\n");
545 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
546 getRAnglebracket(in
); //</facility>
549 /*****************************************************************************
551 * parseEvent : generate event from event definition
553 * fac : facility holding the event
554 * in : input file handle
556 * unnamed_types : array of unamed types
557 * named_types : array of named types
559 * ev : new event (parameters are passed to it)
560 ****************************************************************************/
562 void parseEvent(facility_t
*fac
, parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
563 table_t
* named_types
)
569 sequence_init(&(ev
->fields
));
570 //<event name=eventtype_name>
571 getEventAttributes(in
, ev
);
572 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
573 getRAnglebracket(in
);
575 //<description>...</description>
576 ev
->description
= getDescription(in
);
579 /* Events can have multiple fields. each field form at least a function
580 * parameter of the logging function. */
582 getLAnglebracket(in
);
583 token
= getToken(in
);
586 case FORWARDSLASH
: /* </event> */
588 if(strcmp("event",token
))in
->error(in
,"not an event definition");
589 getRAnglebracket(in
); //</event>
592 case NAME
: /* a field */
593 if(strcmp("field",token
))in
->error(in
,"expecting a field");
594 f
= (field_t
*)memAlloc(sizeof(field_t
));
595 sequence_push(&(ev
->fields
),f
);
596 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
599 in
->error(in
, "expecting </event> or <field >");
604 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
606 }else if(in
->type
== NAME
){
607 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
609 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
610 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
611 in
->error(in
,"type must be a struct");
612 }else in
->error(in
, "not a valid type");
614 getLAnglebracket(in
);
616 }else in
->error(in
,"not a struct type");
617 getLAnglebracket(in
);
620 if(strcmp("event",token
))in
->error(in
,"not an event definition");
621 getRAnglebracket(in
); //</event>
625 /*****************************************************************************
627 * parseField : get field infomation from buffer
629 * fac : facility holding the field
630 * in : input file handle
632 * unnamed_types : array of unamed types
633 * named_types : array of named types
634 * tag : is field surrounded by a <field> </field> tag ?
635 ****************************************************************************/
637 void parseFields(facility_t
*fac
, parse_file_t
*in
, field_t
*f
,
638 sequence_t
* unnamed_types
,
639 table_t
* named_types
,
645 //<field name=field_name> <description> <type> </field>
646 getFieldAttributes(in
, f
);
647 if(f
->name
== NULL
) in
->error(in
, "Field not named");
648 getRAnglebracket(in
);
650 f
->description
= getDescription(in
);
652 f
->description
= NULL
;
656 getLAnglebracket(in
);
657 f
->type
= parseType(fac
, in
,NULL
, unnamed_types
, named_types
);
660 getLAnglebracket(in
);
663 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
664 getRAnglebracket(in
); //</field>
669 /*****************************************************************************
671 * parseType : get type information, type can be :
673 * int(size,fmt); uint(size,fmt); float(size,fmt);
674 * string(fmt); enum(size,fmt,(label1,label2...))
676 * array(arraySize, type); sequence(lengthSize,type)
677 * struct(field(name,type,description)...)
682 * in : input file handle
683 * inType : a type descriptor
684 * unnamed_types : array of unamed types
685 * named_types : array of named types
687 * type_descriptor* : a type descriptor
688 ****************************************************************************/
690 type_descriptor_t
*parseType(facility_t
*fac
, parse_file_t
*in
, type_descriptor_t
*inType
,
691 sequence_t
* unnamed_types
, table_t
* named_types
)
694 type_descriptor_t
*t
;
698 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
702 sequence_push(unnamed_types
,t
);
709 if(strcmp(token
,"struct") == 0) {
711 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
712 getRAnglebracket(in
); //<struct>
713 getLAnglebracket(in
); //<field name=..>
714 token
= getToken(in
);
715 sequence_init(&(t
->fields
));
716 while(strcmp("field",token
) == 0){
717 f
= (field_t
*)memAlloc(sizeof(field_t
));
718 sequence_push(&(t
->fields
),f
);
720 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
723 getLAnglebracket(in
);
724 token
= getToken(in
);
726 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
728 if(strcmp("struct",token
)!=0)
729 in
->error(in
,"not a valid structure definition");
730 getRAnglebracket(in
); //</struct>
732 else if(strcmp(token
,"union") == 0) {
734 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
735 getRAnglebracket(in
); //<union>
737 getLAnglebracket(in
); //<field name=..>
738 token
= getToken(in
);
739 sequence_init(&(t
->fields
));
740 while(strcmp("field",token
) == 0){
741 f
= (field_t
*)memAlloc(sizeof(field_t
));
742 sequence_push(&(t
->fields
),f
);
743 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
746 getLAnglebracket(in
);
747 token
= getToken(in
);
749 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
751 if(strcmp("union",token
)!=0)
752 in
->error(in
,"not a valid union definition");
753 getRAnglebracket(in
); //</union>
755 else if(strcmp(token
,"array") == 0) {
757 sequence_init(&(t
->fields
));
758 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
759 if(t
->size
== 0) in
->error(in
, "Array has empty size");
761 getRAnglebracket(in
); //<array size=n>
763 //getLAnglebracket(in); //<subtype>
765 f
= (field_t
*)memAlloc(sizeof(field_t
));
768 sequence_push(&(t
->fields
),f
);
769 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
771 //getLAnglebracket(in); //<type struct>
772 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
774 getLAnglebracket(in
); //</array>
777 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
778 getRAnglebracket(in
); //</array>
780 else if(strcmp(token
,"sequence") == 0) {
782 sequence_init(&(t
->fields
));
783 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
785 getRAnglebracket(in
); //<sequence>
787 //getLAnglebracket(in); //<sequence size type>
789 f
= (field_t
*)memAlloc(sizeof(field_t
));
791 sequence_push(&(t
->fields
),f
);
792 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
794 //getLAnglebracket(in); //<subtype>
796 f
= (field_t
*)memAlloc(sizeof(field_t
));
798 sequence_push(&(t
->fields
),f
);
799 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
801 //getLAnglebracket(in); //<type sequence>
802 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
804 //getLAnglebracket(in); //<type sequence>
806 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
808 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
809 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
810 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
820 in
->error(in
, "Wrong length type for sequence");
823 getLAnglebracket(in
); //</sequence>
826 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
827 getRAnglebracket(in
); //</sequence>
829 else if(strcmp(token
,"enum") == 0) {
831 long long value
= -1;
834 sequence_init(&(t
->labels
));
835 sequence_init(&(t
->labels_values
));
836 sequence_init(&(t
->labels_description
));
837 t
->already_printed
= 0;
838 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
839 //if(t->size == 0) in->error(in, "Sequence has empty size");
840 //Mathieu : we fix enum size to target int size. GCC is always like this.
841 //fox copy optimisation.
842 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
844 getRAnglebracket(in
);
846 //<label name=label1 value=n/>
847 getLAnglebracket(in
);
848 token
= getToken(in
); //"label" or "/"
849 while(strcmp("label",token
) == 0){
850 int *label_value
= malloc(sizeof(int));
854 str
= allocAndCopy(getNameAttribute(in
));
855 has_value
= getValueAttribute(in
, &loc_value
);
857 sequence_push(&(t
->labels
),str
);
859 if(has_value
) value
= loc_value
;
862 *label_value
= value
;
863 sequence_push(&(t
->labels_values
), label_value
);
866 getRAnglebracket(in
);
868 //read description if any. May be NULL.
869 str
= allocAndCopy(getDescription(in
));
870 sequence_push(&(t
->labels_description
),str
);
872 //next label definition
873 getLAnglebracket(in
);
874 token
= getToken(in
); //"label" or "/"
876 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
878 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
879 getRAnglebracket(in
); //</label>
881 else if(strcmp(token
,"int_fixed") == 0) {
883 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
884 if(t
->size
== 0) in
->error(in
, "int has empty size");
886 getRAnglebracket(in
);
888 else if(strcmp(token
,"uint_fixed") == 0) {
889 t
->type
= UINT_FIXED
;
890 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
891 if(t
->size
== 0) in
->error(in
, "uint has empty size");
893 getRAnglebracket(in
);
895 else if(strcmp(token
,"char") == 0) {
897 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
900 getRAnglebracket(in
);
902 else if(strcmp(token
,"uchar") == 0) {
904 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
907 getRAnglebracket(in
);
909 else if(strcmp(token
,"short") == 0) {
911 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
914 getRAnglebracket(in
);
916 else if(strcmp(token
,"ushort") == 0) {
918 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
921 getRAnglebracket(in
);
923 else if(strcmp(token
,"int") == 0) {
925 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
927 getRAnglebracket(in
);
929 else if(strcmp(token
,"uint") == 0) {
931 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
933 getRAnglebracket(in
);
936 else if(strcmp(token
,"pointer") == 0) {
938 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
940 getRAnglebracket(in
);
942 else if(strcmp(token
,"long") == 0) {
944 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
946 getRAnglebracket(in
);
948 else if(strcmp(token
,"ulong") == 0) {
950 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
952 getRAnglebracket(in
);
954 else if(strcmp(token
,"size_t") == 0) {
956 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
958 getRAnglebracket(in
);
960 else if(strcmp(token
,"ssize_t") == 0) {
962 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
964 getRAnglebracket(in
);
966 else if(strcmp(token
,"off_t") == 0) {
968 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
970 getRAnglebracket(in
);
972 else if(strcmp(token
,"float") == 0) {
974 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
976 getRAnglebracket(in
);
978 else if(strcmp(token
,"string") == 0) {
980 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
982 getRAnglebracket(in
);
984 else if(strcmp(token
,"typeref") == 0){
985 // Must be a named type
987 sequence_pop(unnamed_types
);
988 token
= getNameAttribute(in
);
989 t
= find_named_type(token
, named_types
);
990 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
991 getForwardslash(in
); //<typeref name=type_name/>
992 getRAnglebracket(in
);
994 }else in
->error(in
,"not a valid type");
999 /*****************************************************************************
1001 * find_named_type : find a named type from hash table
1004 * named_types : array of named types
1006 * type_descriptor * : a type descriptor
1007 *****************************************************************************/
1009 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
1011 type_descriptor_t
*t
;
1013 t
= (type_descriptor_t
*)table_find(named_types
,name
);
1018 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
1020 type_descriptor_t
*t
;
1022 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
1023 t
->type_name
= allocAndCopy(name
);
1026 table_insert(named_types
,t
->type_name
,t
);
1027 // table_insert(named_types,allocAndCopy(name),t);
1031 /*****************************************************************************
1033 * parseTypeDefinition : get type information from type definition
1036 * in : input file handle
1037 * unnamed_types : array of unamed types
1038 * named_types : array of named types
1039 *****************************************************************************/
1041 void parseTypeDefinition(facility_t
*fac
, parse_file_t
* in
, sequence_t
* unnamed_types
,
1042 table_t
* named_types
)
1045 type_descriptor_t
*t
;
1047 token
= getNameAttribute(in
);
1048 if(token
== NULL
) in
->error(in
, "Type has empty name");
1049 t
= create_named_type(token
, named_types
);
1051 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
1052 getRAnglebracket(in
); //<type name=type_name>
1053 getLAnglebracket(in
); //<
1054 token
= getName(in
);
1055 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
1057 parseType(fac
, in
,t
, unnamed_types
, named_types
);
1060 getLAnglebracket(in
);
1061 getForwardslash(in
);
1062 token
= getName(in
);
1063 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
1064 getRAnglebracket(in
); //</type>
1067 /**************************************************************************
1069 * getComa, getName, getNumber, getEqual
1071 * Read a token from the input file, check its type, return it scontent.
1074 * in , input file handle.
1077 * address of token content.
1079 **************************************************************************/
1081 char *getName(parse_file_t
* in
)
1085 token
= getToken(in
);
1086 // Optional descriptions
1087 // if(in->type != NAME) in->error(in,"Name token was expected");
1091 int getNumber(parse_file_t
* in
)
1095 token
= getToken(in
);
1096 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
1100 char *getForwardslash(parse_file_t
* in
)
1104 token
= getToken(in
);
1105 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1106 /* Mathieu : final / is optional now. */
1107 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1112 char *getLAnglebracket(parse_file_t
* in
)
1116 token
= getToken(in
);
1117 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1121 char *getRAnglebracket(parse_file_t
* in
)
1125 token
= getToken(in
);
1126 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1130 char *getQuotedString(parse_file_t
* in
)
1134 token
= getToken(in
);
1135 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1139 char * getEqual(parse_file_t
*in
)
1143 token
= getToken(in
);
1144 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1148 int seekNextChar(parse_file_t
*in
)
1151 while((car
= getc(in
->fp
)) != EOF
) {
1160 /******************************************************************
1162 * getToken, ungetToken
1164 * Read a token from the input file and return its type and content.
1165 * Line numbers are accounted for and whitespace/comments are skipped.
1168 * in, input file handle.
1171 * address of token content.
1173 ******************************************************************/
1175 void ungetToken(parse_file_t
* in
)
1180 char *getToken(parse_file_t
* in
)
1184 int pos
= 0, escaped
;
1186 if(in
->unget
== 1) {
1191 /* skip whitespace and comments */
1193 while((car
= getc(fp
)) != EOF
) {
1196 if(car1
== '*') skipComment(in
);
1197 else if(car1
== '/') skipEOL(in
);
1199 car1
= ungetc(car1
,fp
);
1203 else if(car
== '\n') in
->lineno
++;
1204 else if(!isspace(car
)) break;
1212 in
->type
= FORWARDSLASH
;
1213 in
->buffer
[pos
] = car
;
1217 in
->type
= LANGLEBRACKET
;
1218 in
->buffer
[pos
] = car
;
1222 in
->type
= RANGLEBRACKET
;
1223 in
->buffer
[pos
] = car
;
1228 in
->buffer
[pos
] = car
;
1233 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1234 if(car
== '\\' && escaped
== 0) {
1235 in
->buffer
[pos
] = car
;
1240 if(car
== '"' && escaped
== 0) break;
1241 if(car
== '\n' && escaped
== 0) {
1242 in
->error(in
, "non escaped newline inside quoted string");
1244 if(car
== '\n') in
->lineno
++;
1245 in
->buffer
[pos
] = car
;
1249 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1250 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1251 in
->type
= QUOTEDSTRING
;
1255 in
->buffer
[pos
] = car
;
1257 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1262 in
->buffer
[pos
] = car
;
1265 if(car
== EOF
) ungetc(car
,fp
);
1266 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1269 else if(isalnum(car
) || car
== '_' || car
== '-') {
1270 in
->buffer
[0] = car
;
1272 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1273 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1277 in
->buffer
[pos
] = car
;
1280 if(car
== EOF
) ungetc(car
,fp
);
1281 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1283 } else if(car
== '?') {
1284 in
->buffer
[0] = car
;
1287 else in
->error(in
, "invalid character, unrecognized token");
1289 in
->buffer
[pos
] = 0;
1293 void skipComment(parse_file_t
* in
)
1296 while((car
= getc(in
->fp
)) != EOF
) {
1297 if(car
== '\n') in
->lineno
++;
1298 else if(car
== '*') {
1300 if(car
==EOF
) break;
1301 if(car
== '/') return;
1305 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1308 void skipEOL(parse_file_t
* in
)
1311 while((car
= getc(in
->fp
)) != EOF
) {
1317 if(car
== EOF
)ungetc(car
, in
->fp
);
1320 /*****************************************************************************
1322 * checkNamedTypesImplemented : check if all named types have definition
1323 ****************************************************************************/
1325 void checkNamedTypesImplemented(table_t
* named_types
)
1327 type_descriptor_t
*t
;
1331 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1332 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1333 if(t
->type
== NONE
){
1334 sprintf(str
,"named type '%s' has no definition",
1335 (char*)named_types
->keys
.array
[pos
]);
1336 error_callback(NULL
,str
);
1342 /*****************************************************************************
1344 * generateChecksum : generate checksum for the facility
1346 * facName : name of facility
1348 * checksum : checksum for the facility
1349 ****************************************************************************/
1351 void generateChecksum(char* facName
,
1352 unsigned int * checksum
, sequence_t
* events
)
1359 crc
= crc32(facName
);
1360 for(pos
= 0; pos
< events
->position
; pos
++){
1361 ev
= (event_t
*)(events
->array
[pos
]);
1362 crc
= partial_crc32(ev
->name
, crc
);
1363 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1364 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1365 crc
= partial_crc32(f
->name
, crc
);
1366 crc
= getTypeChecksum(crc
, f
->type
);
1372 /*****************************************************************************
1374 * getTypeChecksum : generate checksum by type info
1376 * crc : checksum generated so far
1377 * type : type descriptor containing type info
1379 * unsigned long : checksum
1380 *****************************************************************************/
1382 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1384 unsigned long crc
= aCrc
;
1385 char * str
= NULL
, buf
[16];
1391 str
= intOutputTypes
[getSizeindex(type
->size
)];
1394 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1397 str
= allocAndCopy("void *");
1401 str
= allocAndCopy("signed char");
1405 str
= allocAndCopy("unsigned char");
1409 str
= allocAndCopy("short");
1413 str
= allocAndCopy("unsigned short");
1417 str
= allocAndCopy("int");
1421 str
= allocAndCopy("uint");
1425 str
= allocAndCopy("long");
1429 str
= allocAndCopy("unsigned long");
1433 str
= allocAndCopy("size_t");
1437 str
= allocAndCopy("ssize_t");
1441 str
= allocAndCopy("off_t");
1445 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1448 str
= allocAndCopy("string");
1452 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1453 str
= allocAndCopy("enum");
1457 sprintf(buf
,"%zu", type
->size
);
1458 str
= appendString("array ",buf
);
1462 str
= allocAndCopy("sequence ");
1466 str
= allocAndCopy("struct");
1470 str
= allocAndCopy("union");
1474 error_callback(NULL
, "named type has no definition");
1478 crc
= partial_crc32(str
,crc
);
1481 //the format string is not included in the crc calculation
1483 //if(type->fmt) crc = partial_crc32(type->fmt,crc);
1485 if(type
->type
== ARRAY
){
1486 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1487 } else if(type
->type
==SEQUENCE
) {
1488 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1489 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1490 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1491 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1492 fld
= (field_t
*) type
->fields
.array
[pos
];
1493 crc
= partial_crc32(fld
->name
,crc
);
1494 crc
= getTypeChecksum(crc
, fld
->type
);
1496 }else if(type
->type
== ENUM
){
1497 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1498 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1505 /* Event type descriptors */
1506 void freeType(type_descriptor_t
* tp
)
1511 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1512 if(tp
->type
== ENUM
) {
1513 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1514 free(tp
->labels
.array
[pos2
]);
1516 sequence_dispose(&(tp
->labels
));
1517 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1518 free(tp
->labels_values
.array
[pos2
]);
1520 sequence_dispose(&(tp
->labels_values
));
1522 if(tp
->type
== STRUCT
) {
1523 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1524 f
= (field_t
*) tp
->fields
.array
[pos2
];
1526 free(f
->description
);
1529 sequence_dispose(&(tp
->fields
));
1533 void freeNamedType(table_t
* t
)
1536 type_descriptor_t
* td
;
1538 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1539 free((char *)t
->keys
.array
[pos
]);
1540 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1546 void freeTypes(sequence_t
*t
)
1549 type_descriptor_t
*tp
;
1551 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1552 tp
= (type_descriptor_t
*)t
->array
[pos
];
1558 void freeEvents(sequence_t
*t
)
1563 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1564 ev
= (event_t
*) t
->array
[pos
];
1566 free(ev
->description
);
1567 sequence_dispose(&ev
->fields
);
1574 /* Extensible array */
1576 void sequence_init(sequence_t
*t
)
1580 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1583 void sequence_dispose(sequence_t
*t
)
1590 void sequence_push(sequence_t
*t
, void *elem
)
1594 if(t
->position
>= t
->size
) {
1596 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1597 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1598 t
->size
= t
->size
* 2;
1601 t
->array
[t
->position
] = elem
;
1605 void *sequence_pop(sequence_t
*t
)
1607 if(t
->position
== 0) printf("Error : trying to pop an empty sequence");
1608 return t
->array
[--t
->position
];
1612 /* Hash table API, implementation is just linear search for now */
1614 void table_init(table_t
*t
)
1616 sequence_init(&(t
->keys
));
1617 sequence_init(&(t
->values
));
1620 void table_dispose(table_t
*t
)
1622 sequence_dispose(&(t
->keys
));
1623 sequence_dispose(&(t
->values
));
1626 void table_insert(table_t
*t
, char *key
, void *value
)
1628 sequence_push(&(t
->keys
),key
);
1629 sequence_push(&(t
->values
),value
);
1632 void *table_find(table_t
*t
, char *key
)
1635 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1636 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1637 return(t
->values
.array
[pos
]);
1642 void table_insert_int(table_t
*t
, int *key
, void *value
)
1644 sequence_push(&(t
->keys
),key
);
1645 sequence_push(&(t
->values
),value
);
1648 void *table_find_int(table_t
*t
, int *key
)
1651 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1652 if(*key
== *(int *)t
->keys
.array
[pos
])
1653 return(t
->values
.array
[pos
]);
1659 /* Concatenate strings */
1661 char *appendString(char *s
, char *suffix
)
1664 if(suffix
== NULL
) return s
;
1666 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.066506 seconds and 4 git commands to generate.