3 parser.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2005, Mathieu Desnoyers
7 Copyright (C) 2002, Xianxiu Yang
8 Copyright (C) 2002, Michel Dagenais
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* This program reads the ".xml" event definitions input files
24 and constructs structure for each event.
26 The program uses a very simple tokenizer, called from a hand written
27 recursive descent parser to fill a data structure describing the events.
28 The result is a sequence of events definitions which refer to type
31 A table of named types is maintained to allow refering to types by name
32 when the same type is used at several places. Finally a sequence of
33 all types is maintained to facilitate the freeing of all type
34 information when the processing of an ".xml" file is finished. */
40 #include <linux/errno.h>
47 char *intOutputTypes
[] = {
48 "int8_t", "int16_t", "int32_t", "int64_t" };
50 char *uintOutputTypes
[] = {
51 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
53 char *floatOutputTypes
[] = {
54 "undef", "undef", "float", "double" };
60 void strupper(char *string
)
71 int getSizeindex(unsigned int value
)
83 printf("Error : unknown value size %d\n", value
);
88 /*****************************************************************************
90 * getSize : translate from string to integer
92 * in : input file handle
95 *****************************************************************************/
97 unsigned long long int getSize(parse_file_t
*in
)
100 unsigned long long int ret
;
102 token
= getToken(in
);
105 if(in
->type
== QUOTEDSTRING
) {
109 if (!isdigit(*token2
)) {
110 in
->type
= QUOTEDSTRING
;
113 } while (*(++token2
) != '\0');
116 if(in
->type
== NUMBER
) {
117 ret
= strtoull(token
, NULL
, 0);
124 in
->error(in
,"incorrect size specification");
128 /*****************************************************************************
130 * error_callback : print out error info
132 * in : input file handle
133 * msg : message to be printed
134 ****************************************************************************/
136 void error_callback(parse_file_t
*in
, char *msg
)
139 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
146 /*****************************************************************************
148 * memAlloc : allocate memory
150 * size : required memory size
152 * void * : pointer to allocate memory or NULL
153 ****************************************************************************/
155 void * memAlloc(int size
)
158 if(size
== 0) return NULL
;
161 printf("Failed to allocate memory");
167 /*****************************************************************************
169 * allocAndCopy : allocate memory and initialize it
171 * str : string to be put in memory
173 * char * : pointer to allocate memory or NULL
174 ****************************************************************************/
176 char *allocAndCopy(char *str
)
179 if(str
== NULL
) return NULL
;
180 addr
= (char *)memAlloc(strlen(str
)+1);
185 /**************************************************************************
189 * Read the attribute from the input file.
192 * in , input file handle.
193 * t , the type descriptor to fill.
195 **************************************************************************/
197 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
198 sequence_t
* unnamed_types
, table_t
* named_types
)
209 token
= getToken(in
);
210 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
215 if(!strcmp("format",token
)) {
217 t
->fmt
= allocAndCopy(getQuotedString(in
));
218 //} else if(!strcmp("name",token)) {
220 // car = seekNextChar(in);
221 // if(car == EOF) in->error(in,"name was expected");
222 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
223 // else t->type_name = allocAndCopy(getName(in));
224 } else if(!strcmp("size",token
)) {
226 t
->size
= getSize(in
);
227 } else if(!strcmp("custom_write", token
)) {
229 } else if(!strcmp("byte_order",token
)) {
231 car
= seekNextChar(in
);
232 if(car
== EOF
) in
->error(in
,"byte order was expected (network?)");
233 else if(car
== '\"') token
= getQuotedString(in
);
234 else token
= getName(in
);
235 if(!strcmp("network", token
)) {
238 } else if(!strcmp("write",token
)) {
240 car
= seekNextChar(in
);
241 if(car
== EOF
) in
->error(in
,"write type was expected (custom?)");
242 else if(car
== '\"') token
= getQuotedString(in
);
243 else token
= getName(in
);
244 if(!strcmp("custom", token
)) {
251 /**************************************************************************
255 * Read the attribute from the input file.
258 * in , input file handle.
259 * ev , the event to fill.
261 **************************************************************************/
263 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
270 ev
->per_tracefile
= 0;
271 ev
->param_buffer
= 0;
272 ev
->no_instrument_function
= 0;
273 ev
->high_priority
= 0;
275 ev
->compact_data
= 0;
278 token
= getToken(in
);
279 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
284 if(!strcmp("name",token
)) {
286 car
= seekNextChar(in
);
287 if(car
== EOF
) in
->error(in
,"name was expected");
288 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
289 else ev
->name
= allocAndCopy(getName(in
));
290 } else if(!strcmp("scope", token
)) {
292 car
= seekNextChar(in
);
293 if(car
== EOF
) in
->error(in
,"scope was expected");
294 else if(car
== '\"') token
= getQuotedString(in
);
295 else token
= getName(in
);
296 if(!strcmp(token
, "trace")) ev
->per_trace
= 1;
297 else if(!strcmp(token
, "tracefile")) ev
->per_tracefile
= 1;
298 } else if(!strcmp("param", token
)) {
300 car
= seekNextChar(in
);
301 if(car
== EOF
) in
->error(in
,"parameter type was expected");
302 else if(car
== '\"') token
= getQuotedString(in
);
303 else token
= getName(in
);
304 if(!strcmp(token
, "buffer")) ev
->param_buffer
= 1;
305 } else if(!strcmp("attribute", token
)) {
307 car
= seekNextChar(in
);
308 if(car
== EOF
) in
->error(in
,"attribute was expected");
309 else if(car
== '\"') token
= getQuotedString(in
);
310 else token
= getName(in
);
311 if(!strcmp(token
, "no_instrument_function"))
312 ev
->no_instrument_function
= 1;
313 else if(!strcmp(token
, "high_priority"))
314 ev
->high_priority
= 1;
315 else if(!strcmp(token
, "force"))
317 else if(!strcmp(token
, "compact_data"))
318 ev
->compact_data
= 1;
323 /**************************************************************************
325 * getFacilityAttributes
327 * Read the attribute from the input file.
330 * in , input file handle.
331 * fac , the facility to fill.
333 **************************************************************************/
335 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
346 token
= getToken(in
);
347 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
352 if(!strcmp("name",token
)) {
354 car
= seekNextChar(in
);
355 if(car
== EOF
) in
->error(in
,"name was expected");
356 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
357 else fac
->name
= allocAndCopy(getName(in
));
358 if(!strncmp(fac
->name
, "user_", sizeof("user_")-1))
360 } else if(!strcmp("arch", token
)) {
362 car
= seekNextChar(in
);
363 if(car
== '\"') fac
->arch
= allocAndCopy(getQuotedString(in
));
364 else fac
->arch
= allocAndCopy(getName(in
));
365 } else if(!strcmp("align", token
)) {
367 fac
->align
= getSize(in
);
373 /**************************************************************************
377 * Read the attribute from the input file.
380 * in , input file handle.
381 * f , the field to fill.
383 **************************************************************************/
385 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
393 token
= getToken(in
);
394 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
399 if(!strcmp("name",token
)) {
401 car
= seekNextChar(in
);
402 if(car
== EOF
) in
->error(in
,"name was expected");
403 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
404 else f
->name
= allocAndCopy(getName(in
));
409 char *getNameAttribute(parse_file_t
*in
)
416 token
= getToken(in
);
417 if(!strcmp("name",token
)) {
419 car
= seekNextChar(in
);
420 if(car
== EOF
) in
->error(in
,"name was expected");
421 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
422 else name
= allocAndCopy(getName(in
));
429 if(name
== NULL
) in
->error(in
, "Name was expected");
435 //for <label name=label_name value=n format="...">, value is an option
436 //Return value : 0 : no value, 1 : has a value
437 int getValueAttribute(parse_file_t
*in
, long long *value
)
439 char * token
, *token2
;
441 token
= getToken(in
);
443 if(strcmp("/",token
) == 0 || strcmp(">", token
) == 0){
447 if(strcmp("value",token
))in
->error(in
,"value was expected");
450 token
= getToken(in
);
452 if(in
->type
== QUOTEDSTRING
) {
456 if (!isdigit(*token2
)) {
457 in
->type
= QUOTEDSTRING
;
460 } while (*(++token2
) != '\0');
463 if(in
->type
== NUMBER
)
464 *value
= strtoll(token
, NULL
, 0);
469 in
->error(in
,"incorrect size specification");
473 char * getDescription(parse_file_t
*in
)
481 getLAnglebracket(in
);
483 if(strcmp("description",token
)){
484 fseek(in
->fp
, pos
, SEEK_SET
);
488 getRAnglebracket(in
);
491 while((car
= getc(in
->fp
)) != EOF
) {
492 if(car
== '<') break;
493 if(car
== '\0') continue;
494 in
->buffer
[pos
] = car
;
497 if(car
== EOF
)in
->error(in
,"not a valid description");
498 in
->buffer
[pos
] = '\0';
500 str
= allocAndCopy(in
->buffer
);
504 if(strcmp("description", token
))in
->error(in
,"not a valid description");
505 getRAnglebracket(in
);
510 /*****************************************************************************
512 * parseFacility : generate event list
514 * in : input file handle
515 * fac : empty facility
517 * fac : facility filled with event list
518 ****************************************************************************/
520 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
525 getFacilityAttributes(in
, fac
);
526 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
528 fac
->capname
= allocAndCopy(fac
->name
);
529 strupper(fac
->capname
);
530 getRAnglebracket(in
);
532 fac
->description
= getDescription(in
);
535 getLAnglebracket(in
);
537 token
= getToken(in
);
538 if(in
->type
== ENDFILE
)
539 in
->error(in
,"the definition of the facility is not finished");
541 if(strcmp("event",token
) == 0){
542 ev
= (event_t
*) memAlloc(sizeof(event_t
));
543 sequence_push(&(fac
->events
),ev
);
544 parseEvent(fac
, in
, ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
545 }else if(strcmp("type",token
) == 0){
546 parseTypeDefinition(fac
, in
, &(fac
->unnamed_types
), &(fac
->named_types
));
547 }else if(in
->type
== FORWARDSLASH
){
549 }else in
->error(in
,"event or type token expected\n");
553 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
554 getRAnglebracket(in
); //</facility>
557 /*****************************************************************************
559 * parseEvent : generate event from event definition
561 * fac : facility holding the event
562 * in : input file handle
564 * unnamed_types : array of unamed types
565 * named_types : array of named types
567 * ev : new event (parameters are passed to it)
568 ****************************************************************************/
570 void parseEvent(facility_t
*fac
, parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
571 table_t
* named_types
)
577 sequence_init(&(ev
->fields
));
578 //<event name=eventtype_name>
579 getEventAttributes(in
, ev
);
580 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
581 getRAnglebracket(in
);
583 //<description>...</description>
584 ev
->description
= getDescription(in
);
587 /* Events can have multiple fields. each field form at least a function
588 * parameter of the logging function. */
590 getLAnglebracket(in
);
591 token
= getToken(in
);
594 case FORWARDSLASH
: /* </event> */
596 if(strcmp("event",token
))in
->error(in
,"not an event definition");
597 getRAnglebracket(in
); //</event>
600 case NAME
: /* a field */
601 if(strcmp("field",token
))in
->error(in
,"expecting a field");
602 f
= (field_t
*)memAlloc(sizeof(field_t
));
603 sequence_push(&(ev
->fields
),f
);
604 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
607 in
->error(in
, "expecting </event> or <field >");
612 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
614 }else if(in
->type
== NAME
){
615 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
617 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
618 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
619 in
->error(in
,"type must be a struct");
620 }else in
->error(in
, "not a valid type");
622 getLAnglebracket(in
);
624 }else in
->error(in
,"not a struct type");
625 getLAnglebracket(in
);
628 if(strcmp("event",token
))in
->error(in
,"not an event definition");
629 getRAnglebracket(in
); //</event>
633 /*****************************************************************************
635 * parseField : get field infomation from buffer
637 * fac : facility holding the field
638 * in : input file handle
640 * unnamed_types : array of unamed types
641 * named_types : array of named types
642 * tag : is field surrounded by a <field> </field> tag ?
643 ****************************************************************************/
645 void parseFields(facility_t
*fac
, parse_file_t
*in
, field_t
*f
,
646 sequence_t
* unnamed_types
,
647 table_t
* named_types
,
653 //<field name=field_name> <description> <type> </field>
654 getFieldAttributes(in
, f
);
655 if(f
->name
== NULL
) in
->error(in
, "Field not named");
656 getRAnglebracket(in
);
658 f
->description
= getDescription(in
);
660 f
->description
= NULL
;
664 getLAnglebracket(in
);
665 f
->type
= parseType(fac
, in
,NULL
, unnamed_types
, named_types
);
668 getLAnglebracket(in
);
671 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
672 getRAnglebracket(in
); //</field>
677 /*****************************************************************************
679 * parseType : get type information, type can be :
681 * int(size,fmt); uint(size,fmt); float(size,fmt);
682 * string(fmt); enum(size,fmt,(label1,label2...))
684 * array(arraySize, type); sequence(lengthSize,type)
685 * struct(field(name,type,description)...)
690 * in : input file handle
691 * inType : a type descriptor
692 * unnamed_types : array of unamed types
693 * named_types : array of named types
695 * type_descriptor* : a type descriptor
696 ****************************************************************************/
698 type_descriptor_t
*parseType(facility_t
*fac
, parse_file_t
*in
, type_descriptor_t
*inType
,
699 sequence_t
* unnamed_types
, table_t
* named_types
)
702 type_descriptor_t
*t
;
706 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
710 sequence_push(unnamed_types
,t
);
717 if(strcmp(token
,"struct") == 0) {
719 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
720 getRAnglebracket(in
); //<struct>
721 getLAnglebracket(in
); //<field name=..>
722 token
= getToken(in
);
723 sequence_init(&(t
->fields
));
724 while(strcmp("field",token
) == 0){
725 f
= (field_t
*)memAlloc(sizeof(field_t
));
726 sequence_push(&(t
->fields
),f
);
728 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
731 getLAnglebracket(in
);
732 token
= getToken(in
);
734 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
736 if(strcmp("struct",token
)!=0)
737 in
->error(in
,"not a valid structure definition");
738 getRAnglebracket(in
); //</struct>
740 else if(strcmp(token
,"union") == 0) {
742 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
743 getRAnglebracket(in
); //<union>
745 getLAnglebracket(in
); //<field name=..>
746 token
= getToken(in
);
747 sequence_init(&(t
->fields
));
748 while(strcmp("field",token
) == 0){
749 f
= (field_t
*)memAlloc(sizeof(field_t
));
750 sequence_push(&(t
->fields
),f
);
751 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 1);
754 getLAnglebracket(in
);
755 token
= getToken(in
);
757 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
759 if(strcmp("union",token
)!=0)
760 in
->error(in
,"not a valid union definition");
761 getRAnglebracket(in
); //</union>
763 else if(strcmp(token
,"array") == 0) {
765 sequence_init(&(t
->fields
));
766 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
767 if(t
->size
== 0) in
->error(in
, "Array has empty size");
769 getRAnglebracket(in
); //<array size=n>
771 //getLAnglebracket(in); //<subtype>
773 f
= (field_t
*)memAlloc(sizeof(field_t
));
776 sequence_push(&(t
->fields
),f
);
777 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
779 //getLAnglebracket(in); //<type struct>
780 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
782 getLAnglebracket(in
); //</array>
785 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
786 getRAnglebracket(in
); //</array>
788 else if(strcmp(token
,"sequence") == 0) {
790 sequence_init(&(t
->fields
));
791 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
793 getRAnglebracket(in
); //<sequence>
795 //getLAnglebracket(in); //<sequence size type>
797 f
= (field_t
*)memAlloc(sizeof(field_t
));
799 sequence_push(&(t
->fields
),f
);
800 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
802 //getLAnglebracket(in); //<subtype>
804 f
= (field_t
*)memAlloc(sizeof(field_t
));
806 sequence_push(&(t
->fields
),f
);
807 parseFields(fac
, in
, f
, unnamed_types
, named_types
, 0);
809 //getLAnglebracket(in); //<type sequence>
810 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
812 //getLAnglebracket(in); //<type sequence>
814 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
816 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
817 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
818 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
828 in
->error(in
, "Wrong length type for sequence");
831 getLAnglebracket(in
); //</sequence>
834 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
835 getRAnglebracket(in
); //</sequence>
837 else if(strcmp(token
,"enum") == 0) {
839 long long value
= -1;
842 sequence_init(&(t
->labels
));
843 sequence_init(&(t
->labels_values
));
844 sequence_init(&(t
->labels_description
));
845 t
->already_printed
= 0;
846 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
847 //if(t->size == 0) in->error(in, "Sequence has empty size");
848 //Mathieu : we fix enum size to target int size. GCC is always like this.
849 //fox copy optimisation.
850 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
852 getRAnglebracket(in
);
854 //<label name=label1 value=n/>
855 getLAnglebracket(in
);
856 token
= getToken(in
); //"label" or "/"
857 while(strcmp("label",token
) == 0){
858 int *label_value
= malloc(sizeof(int));
862 str
= allocAndCopy(getNameAttribute(in
));
863 has_value
= getValueAttribute(in
, &loc_value
);
865 sequence_push(&(t
->labels
),str
);
867 if(has_value
) value
= loc_value
;
870 *label_value
= value
;
871 sequence_push(&(t
->labels_values
), label_value
);
874 getRAnglebracket(in
);
876 //read description if any. May be NULL.
877 str
= allocAndCopy(getDescription(in
));
878 sequence_push(&(t
->labels_description
),str
);
880 //next label definition
881 getLAnglebracket(in
);
882 token
= getToken(in
); //"label" or "/"
884 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
886 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
887 getRAnglebracket(in
); //</label>
889 else if(strcmp(token
,"int_fixed") == 0) {
891 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
892 if(t
->size
== 0) in
->error(in
, "int has empty size");
894 getRAnglebracket(in
);
896 else if(strcmp(token
,"uint_fixed") == 0) {
897 t
->type
= UINT_FIXED
;
898 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
899 if(t
->size
== 0) in
->error(in
, "uint has empty size");
901 getRAnglebracket(in
);
903 else if(strcmp(token
,"char") == 0) {
905 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
908 getRAnglebracket(in
);
910 else if(strcmp(token
,"uchar") == 0) {
912 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
915 getRAnglebracket(in
);
917 else if(strcmp(token
,"short") == 0) {
919 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
922 getRAnglebracket(in
);
924 else if(strcmp(token
,"ushort") == 0) {
926 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
929 getRAnglebracket(in
);
931 else if(strcmp(token
,"int") == 0) {
933 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
935 getRAnglebracket(in
);
937 else if(strcmp(token
,"uint") == 0) {
939 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
941 getRAnglebracket(in
);
944 else if(strcmp(token
,"pointer") == 0) {
946 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
948 getRAnglebracket(in
);
950 else if(strcmp(token
,"long") == 0) {
952 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
954 getRAnglebracket(in
);
956 else if(strcmp(token
,"ulong") == 0) {
958 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
960 getRAnglebracket(in
);
962 else if(strcmp(token
,"size_t") == 0) {
964 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
966 getRAnglebracket(in
);
968 else if(strcmp(token
,"ssize_t") == 0) {
970 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
972 getRAnglebracket(in
);
974 else if(strcmp(token
,"off_t") == 0) {
976 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
978 getRAnglebracket(in
);
980 else if(strcmp(token
,"float") == 0) {
982 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
984 getRAnglebracket(in
);
986 else if(strcmp(token
,"string") == 0) {
988 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
990 getRAnglebracket(in
);
992 else if(strcmp(token
,"typeref") == 0){
993 // Must be a named type
995 sequence_pop(unnamed_types
);
996 token
= getNameAttribute(in
);
997 t
= find_named_type(token
, named_types
);
998 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
999 getForwardslash(in
); //<typeref name=type_name/>
1000 getRAnglebracket(in
);
1002 }else in
->error(in
,"not a valid type");
1007 /*****************************************************************************
1009 * find_named_type : find a named type from hash table
1012 * named_types : array of named types
1014 * type_descriptor * : a type descriptor
1015 *****************************************************************************/
1017 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
1019 type_descriptor_t
*t
;
1021 t
= (type_descriptor_t
*)table_find(named_types
,name
);
1026 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
1028 type_descriptor_t
*t
;
1030 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
1031 t
->type_name
= allocAndCopy(name
);
1034 table_insert(named_types
,t
->type_name
,t
);
1035 // table_insert(named_types,allocAndCopy(name),t);
1039 /*****************************************************************************
1041 * parseTypeDefinition : get type information from type definition
1044 * in : input file handle
1045 * unnamed_types : array of unamed types
1046 * named_types : array of named types
1047 *****************************************************************************/
1049 void parseTypeDefinition(facility_t
*fac
, parse_file_t
* in
, sequence_t
* unnamed_types
,
1050 table_t
* named_types
)
1053 type_descriptor_t
*t
;
1055 token
= getNameAttribute(in
);
1056 if(token
== NULL
) in
->error(in
, "Type has empty name");
1057 t
= create_named_type(token
, named_types
);
1059 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
1060 getRAnglebracket(in
); //<type name=type_name>
1061 getLAnglebracket(in
); //<
1062 token
= getName(in
);
1063 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
1065 parseType(fac
, in
,t
, unnamed_types
, named_types
);
1068 getLAnglebracket(in
);
1069 getForwardslash(in
);
1070 token
= getName(in
);
1071 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
1072 getRAnglebracket(in
); //</type>
1075 /**************************************************************************
1077 * getComa, getName, getNumber, getEqual
1079 * Read a token from the input file, check its type, return it scontent.
1082 * in , input file handle.
1085 * address of token content.
1087 **************************************************************************/
1089 char *getName(parse_file_t
* in
)
1093 token
= getToken(in
);
1094 // Optional descriptions
1095 // if(in->type != NAME) in->error(in,"Name token was expected");
1099 int getNumber(parse_file_t
* in
)
1103 token
= getToken(in
);
1104 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
1108 char *getForwardslash(parse_file_t
* in
)
1112 token
= getToken(in
);
1113 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1114 /* Mathieu : final / is optional now. */
1115 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1120 char *getLAnglebracket(parse_file_t
* in
)
1124 token
= getToken(in
);
1125 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1129 char *getRAnglebracket(parse_file_t
* in
)
1133 token
= getToken(in
);
1134 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1138 char *getQuotedString(parse_file_t
* in
)
1142 token
= getToken(in
);
1143 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1147 char * getEqual(parse_file_t
*in
)
1151 token
= getToken(in
);
1152 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1156 int seekNextChar(parse_file_t
*in
)
1159 while((car
= getc(in
->fp
)) != EOF
) {
1168 /******************************************************************
1170 * getToken, ungetToken
1172 * Read a token from the input file and return its type and content.
1173 * Line numbers are accounted for and whitespace/comments are skipped.
1176 * in, input file handle.
1179 * address of token content.
1181 ******************************************************************/
1183 void ungetToken(parse_file_t
* in
)
1188 char *getToken(parse_file_t
* in
)
1192 int pos
= 0, escaped
;
1194 if(in
->unget
== 1) {
1199 /* skip whitespace and comments */
1201 while((car
= getc(fp
)) != EOF
) {
1204 if(car1
== '*') skipComment(in
);
1205 else if(car1
== '/') skipEOL(in
);
1207 car1
= ungetc(car1
,fp
);
1211 else if(car
== '\n') in
->lineno
++;
1212 else if(!isspace(car
)) break;
1220 in
->type
= FORWARDSLASH
;
1221 in
->buffer
[pos
] = car
;
1225 in
->type
= LANGLEBRACKET
;
1226 in
->buffer
[pos
] = car
;
1230 in
->type
= RANGLEBRACKET
;
1231 in
->buffer
[pos
] = car
;
1236 in
->buffer
[pos
] = car
;
1241 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1242 if(car
== '\\' && escaped
== 0) {
1243 in
->buffer
[pos
] = car
;
1248 if(car
== '"' && escaped
== 0) break;
1249 if(car
== '\n' && escaped
== 0) {
1250 in
->error(in
, "non escaped newline inside quoted string");
1252 if(car
== '\n') in
->lineno
++;
1253 in
->buffer
[pos
] = car
;
1257 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1258 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1259 in
->type
= QUOTEDSTRING
;
1263 in
->buffer
[pos
] = car
;
1265 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1270 in
->buffer
[pos
] = car
;
1273 if(car
== EOF
) ungetc(car
,fp
);
1274 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1277 else if(isalnum(car
) || car
== '_' || car
== '-') {
1278 in
->buffer
[0] = car
;
1280 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1281 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1285 in
->buffer
[pos
] = car
;
1288 if(car
== EOF
) ungetc(car
,fp
);
1289 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1291 } else if(car
== '?') {
1292 in
->buffer
[0] = car
;
1295 else in
->error(in
, "invalid character, unrecognized token");
1297 in
->buffer
[pos
] = 0;
1301 void skipComment(parse_file_t
* in
)
1304 while((car
= getc(in
->fp
)) != EOF
) {
1305 if(car
== '\n') in
->lineno
++;
1306 else if(car
== '*') {
1308 if(car
==EOF
) break;
1309 if(car
== '/') return;
1313 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1316 void skipEOL(parse_file_t
* in
)
1319 while((car
= getc(in
->fp
)) != EOF
) {
1325 if(car
== EOF
)ungetc(car
, in
->fp
);
1328 /*****************************************************************************
1330 * checkNamedTypesImplemented : check if all named types have definition
1331 ****************************************************************************/
1333 void checkNamedTypesImplemented(table_t
* named_types
)
1335 type_descriptor_t
*t
;
1339 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1340 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1341 if(t
->type
== NONE
){
1342 sprintf(str
,"named type '%s' has no definition",
1343 (char*)named_types
->keys
.array
[pos
]);
1344 error_callback(NULL
,str
);
1350 /*****************************************************************************
1352 * generateChecksum : generate checksum for the facility
1354 * facName : name of facility
1356 * checksum : checksum for the facility
1357 ****************************************************************************/
1359 void generateChecksum(char* facName
,
1360 unsigned int * checksum
, sequence_t
* events
)
1367 crc
= crc32(facName
);
1368 for(pos
= 0; pos
< events
->position
; pos
++){
1369 ev
= (event_t
*)(events
->array
[pos
]);
1370 crc
= partial_crc32(ev
->name
, crc
);
1371 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1372 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1373 crc
= partial_crc32(f
->name
, crc
);
1374 crc
= getTypeChecksum(crc
, f
->type
);
1380 /*****************************************************************************
1382 * getTypeChecksum : generate checksum by type info
1384 * crc : checksum generated so far
1385 * type : type descriptor containing type info
1387 * unsigned long : checksum
1388 *****************************************************************************/
1390 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1392 unsigned long crc
= aCrc
;
1393 char * str
= NULL
, buf
[16];
1399 str
= intOutputTypes
[getSizeindex(type
->size
)];
1402 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1405 str
= allocAndCopy("void *");
1409 str
= allocAndCopy("signed char");
1413 str
= allocAndCopy("unsigned char");
1417 str
= allocAndCopy("short");
1421 str
= allocAndCopy("unsigned short");
1425 str
= allocAndCopy("int");
1429 str
= allocAndCopy("uint");
1433 str
= allocAndCopy("long");
1437 str
= allocAndCopy("unsigned long");
1441 str
= allocAndCopy("size_t");
1445 str
= allocAndCopy("ssize_t");
1449 str
= allocAndCopy("off_t");
1453 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1456 str
= allocAndCopy("string");
1460 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1461 str
= allocAndCopy("enum");
1465 sprintf(buf
,"%zu", type
->size
);
1466 str
= appendString("array ",buf
);
1470 str
= allocAndCopy("sequence ");
1474 str
= allocAndCopy("struct");
1478 str
= allocAndCopy("union");
1482 error_callback(NULL
, "named type has no definition");
1486 crc
= partial_crc32(str
,crc
);
1489 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1491 if(type
->type
== ARRAY
){
1492 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1493 } else if(type
->type
==SEQUENCE
) {
1494 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1495 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1496 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1497 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1498 fld
= (field_t
*) type
->fields
.array
[pos
];
1499 crc
= partial_crc32(fld
->name
,crc
);
1500 crc
= getTypeChecksum(crc
, fld
->type
);
1502 }else if(type
->type
== ENUM
){
1503 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1504 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1511 /* Event type descriptors */
1512 void freeType(type_descriptor_t
* tp
)
1517 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1518 if(tp
->type
== ENUM
) {
1519 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1520 free(tp
->labels
.array
[pos2
]);
1522 sequence_dispose(&(tp
->labels
));
1523 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1524 free(tp
->labels_values
.array
[pos2
]);
1526 sequence_dispose(&(tp
->labels_values
));
1528 if(tp
->type
== STRUCT
) {
1529 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1530 f
= (field_t
*) tp
->fields
.array
[pos2
];
1532 free(f
->description
);
1535 sequence_dispose(&(tp
->fields
));
1539 void freeNamedType(table_t
* t
)
1542 type_descriptor_t
* td
;
1544 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1545 free((char *)t
->keys
.array
[pos
]);
1546 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1552 void freeTypes(sequence_t
*t
)
1555 type_descriptor_t
*tp
;
1557 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1558 tp
= (type_descriptor_t
*)t
->array
[pos
];
1564 void freeEvents(sequence_t
*t
)
1569 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1570 ev
= (event_t
*) t
->array
[pos
];
1572 free(ev
->description
);
1573 sequence_dispose(&ev
->fields
);
1580 /* Extensible array */
1582 void sequence_init(sequence_t
*t
)
1586 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1589 void sequence_dispose(sequence_t
*t
)
1596 void sequence_push(sequence_t
*t
, void *elem
)
1600 if(t
->position
>= t
->size
) {
1602 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1603 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1604 t
->size
= t
->size
* 2;
1607 t
->array
[t
->position
] = elem
;
1611 void *sequence_pop(sequence_t
*t
)
1613 if(t
->position
== 0) printf("Error : trying to pop an empty sequence");
1614 return t
->array
[--t
->position
];
1618 /* Hash table API, implementation is just linear search for now */
1620 void table_init(table_t
*t
)
1622 sequence_init(&(t
->keys
));
1623 sequence_init(&(t
->values
));
1626 void table_dispose(table_t
*t
)
1628 sequence_dispose(&(t
->keys
));
1629 sequence_dispose(&(t
->values
));
1632 void table_insert(table_t
*t
, char *key
, void *value
)
1634 sequence_push(&(t
->keys
),key
);
1635 sequence_push(&(t
->values
),value
);
1638 void *table_find(table_t
*t
, char *key
)
1641 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1642 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1643 return(t
->values
.array
[pos
]);
1648 void table_insert_int(table_t
*t
, int *key
, void *value
)
1650 sequence_push(&(t
->keys
),key
);
1651 sequence_push(&(t
->values
),value
);
1654 void *table_find_int(table_t
*t
, int *key
)
1657 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1658 if(*key
== *(int *)t
->keys
.array
[pos
])
1659 return(t
->values
.array
[pos
]);
1665 /* Concatenate strings */
1667 char *appendString(char *s
, char *suffix
)
1670 if(suffix
== NULL
) return s
;
1672 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.063901 seconds and 4 git commands to generate.