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
)
101 unsigned long long int ret
;
103 token
= getToken(in
);
104 if(token
[0] == '"') {
106 token
= getToken(in
);
108 if(in
->type
== NUMBER
) {
109 ret
= strtoull(token
, NULL
, 0);
114 token
= getToken(in
);
115 if(token
[0] != '"') goto error
;
120 in
->error(in
,"incorrect size specification");
124 /*****************************************************************************
126 * error_callback : print out error info
128 * in : input file handle
129 * msg : message to be printed
130 ****************************************************************************/
132 void error_callback(parse_file_t
*in
, char *msg
)
135 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
142 /*****************************************************************************
144 * memAlloc : allocate memory
146 * size : required memory size
148 * void * : pointer to allocate memory or NULL
149 ****************************************************************************/
151 void * memAlloc(int size
)
154 if(size
== 0) return NULL
;
157 printf("Failed to allocate memory");
163 /*****************************************************************************
165 * allocAndCopy : allocate memory and initialize it
167 * str : string to be put in memory
169 * char * : pointer to allocate memory or NULL
170 ****************************************************************************/
172 char *allocAndCopy(char *str
)
175 if(str
== NULL
) return NULL
;
176 addr
= (char *)memAlloc(strlen(str
)+1);
181 /**************************************************************************
185 * Read the attribute from the input file.
188 * in , input file handle.
189 * t , the type descriptor to fill.
191 **************************************************************************/
193 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
194 sequence_t
* unnamed_types
, table_t
* named_types
)
204 token
= getToken(in
);
205 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
210 if(!strcmp("format",token
)) {
212 t
->fmt
= allocAndCopy(getQuotedString(in
));
213 //} else if(!strcmp("name",token)) {
215 // car = seekNextChar(in);
216 // if(car == EOF) in->error(in,"name was expected");
217 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
218 // else t->type_name = allocAndCopy(getName(in));
219 } else if(!strcmp("size",token
)) {
221 t
->size
= getSize(in
);
222 } else if(!strcmp("custom_write", token
)) {
224 } else if(!strcmp("network", token
)) {
230 /**************************************************************************
234 * Read the attribute from the input file.
237 * in , input file handle.
238 * ev , the event to fill.
240 **************************************************************************/
242 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
249 ev
->per_tracefile
= 0;
250 ev
->param_buffer
= 0;
251 ev
->no_instrument_function
= 0;
254 token
= getToken(in
);
255 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
260 if(!strcmp("name",token
)) {
262 car
= seekNextChar(in
);
263 if(car
== EOF
) in
->error(in
,"name was expected");
264 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
265 else ev
->name
= allocAndCopy(getName(in
));
266 } else if(!strcmp("per_trace", token
)) {
268 } else if(!strcmp("per_tracefile", token
)) {
269 ev
->per_tracefile
= 1;
270 } else if(!strcmp("param_buffer", token
)) {
271 ev
->param_buffer
= 1;
272 } else if(!strcmp("no_instrument_function", token
)) {
273 ev
->no_instrument_function
= 1;
279 /**************************************************************************
281 * getFacilityAttributes
283 * Read the attribute from the input file.
286 * in , input file handle.
287 * fac , the facility to fill.
289 **************************************************************************/
291 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
301 token
= getToken(in
);
302 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
307 if(!strcmp("name",token
)) {
309 car
= seekNextChar(in
);
310 if(car
== EOF
) in
->error(in
,"name was expected");
311 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
312 else fac
->name
= allocAndCopy(getName(in
));
313 if(!strncmp(fac
->name
, "user_", sizeof("user_")) == 0)
315 } else if(!strcmp("arch", token
)) {
317 car
= seekNextChar(in
);
318 if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
319 else fac
->arch
= allocAndCopy(getName(in
));
324 /**************************************************************************
328 * Read the attribute from the input file.
331 * in , input file handle.
332 * f , the field to fill.
334 **************************************************************************/
336 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
344 token
= getToken(in
);
345 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
350 if(!strcmp("name",token
)) {
352 car
= seekNextChar(in
);
353 if(car
== EOF
) in
->error(in
,"name was expected");
354 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
355 else f
->name
= allocAndCopy(getName(in
));
360 char *getNameAttribute(parse_file_t
*in
)
367 token
= getToken(in
);
368 if(!strcmp("name",token
)) {
370 car
= seekNextChar(in
);
371 if(car
== EOF
) in
->error(in
,"name was expected");
372 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
373 else name
= allocAndCopy(getName(in
));
380 if(name
== NULL
) in
->error(in
, "Name was expected");
386 //for <label name=label_name value=n format="..."/>, value is an option
387 //Return value : 0 : no value, 1 : has a value
388 int getValueAttribute(parse_file_t
*in
, long long *value
)
393 token
= getToken(in
);
394 if(strcmp("/",token
) == 0){
399 if(strcmp("value",token
))in
->error(in
,"value was expected");
401 token
= getToken(in
);
403 if(token
[0] == '"') {
405 token
= getToken(in
);
407 if(in
->type
== NUMBER
) {
408 *value
= strtoll(token
, NULL
, 0);
413 token
= getToken(in
);
414 if(token
[0] != '"') goto error
;
419 in
->error(in
,"incorrect size specification");
423 char * getDescription(parse_file_t
*in
)
426 char * token
, car
, *str
;
430 getLAnglebracket(in
);
432 if(strcmp("description",token
)){
433 fseek(in
->fp
, pos
, SEEK_SET
);
437 getRAnglebracket(in
);
440 while((car
= getc(in
->fp
)) != EOF
) {
441 if(car
== '<') break;
442 if(car
== '\0') continue;
443 in
->buffer
[pos
] = car
;
446 if(car
== EOF
)in
->error(in
,"not a valid description");
447 in
->buffer
[pos
] = '\0';
449 str
= allocAndCopy(in
->buffer
);
453 if(strcmp("description", token
))in
->error(in
,"not a valid description");
454 getRAnglebracket(in
);
459 /*****************************************************************************
461 * parseFacility : generate event list
463 * in : input file handle
464 * fac : empty facility
466 * fac : facility filled with event list
467 ****************************************************************************/
469 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
474 getFacilityAttributes(in
, fac
);
475 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
477 fac
->capname
= allocAndCopy(fac
->name
);
478 strupper(fac
->capname
);
479 getRAnglebracket(in
);
481 fac
->description
= getDescription(in
);
484 getLAnglebracket(in
);
486 token
= getToken(in
);
487 if(in
->type
== ENDFILE
)
488 in
->error(in
,"the definition of the facility is not finished");
490 if(strcmp("event",token
) == 0){
491 ev
= (event_t
*) memAlloc(sizeof(event_t
));
492 sequence_push(&(fac
->events
),ev
);
493 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
494 }else if(strcmp("type",token
) == 0){
495 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
496 }else if(in
->type
== FORWARDSLASH
){
498 }else in
->error(in
,"event or type token expected\n");
502 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
503 getRAnglebracket(in
); //</facility>
506 /*****************************************************************************
508 * parseEvent : generate event from event definition
510 * in : input file handle
512 * unnamed_types : array of unamed types
513 * named_types : array of named types
515 * ev : new event (parameters are passed to it)
516 ****************************************************************************/
518 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
519 table_t
* named_types
)
524 sequence_init(&(ev
->fields
));
525 //<event name=eventtype_name>
526 getEventAttributes(in
, ev
);
527 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
528 getRAnglebracket(in
);
530 //<description>...</description>
531 ev
->description
= getDescription(in
);
534 /* Events can have multiple fields. each field form at least a function
535 * parameter of the logging function. */
537 getLAnglebracket(in
);
538 token
= getToken(in
);
541 case FORWARDSLASH
: /* </event> */
543 if(strcmp("event",token
))in
->error(in
,"not an event definition");
544 getRAnglebracket(in
); //</event>
547 case NAME
: /* a field */
548 if(strcmp("field",token
))in
->error(in
,"expecting a field");
549 f
= (field_t
*)memAlloc(sizeof(field_t
));
550 sequence_push(&(ev
->fields
),f
);
551 parseFields(in
, f
, unnamed_types
, named_types
, 1);
554 in
->error(in
, "expecting </event> or <field >");
559 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
561 }else if(in
->type
== NAME
){
562 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
564 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
565 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
566 in
->error(in
,"type must be a struct");
567 }else in
->error(in
, "not a valid type");
569 getLAnglebracket(in
);
571 }else in
->error(in
,"not a struct type");
572 getLAnglebracket(in
);
575 if(strcmp("event",token
))in
->error(in
,"not an event definition");
576 getRAnglebracket(in
); //</event>
580 /*****************************************************************************
582 * parseField : get field infomation from buffer
584 * in : input file handle
586 * unnamed_types : array of unamed types
587 * named_types : array of named types
588 * tag : is field surrounded by a <field> </field> tag ?
589 ****************************************************************************/
591 void parseFields(parse_file_t
*in
, field_t
*f
,
592 sequence_t
* unnamed_types
,
593 table_t
* named_types
,
598 //<field name=field_name> <description> <type> </field>
599 getFieldAttributes(in
, f
);
600 if(f
->name
== NULL
) in
->error(in
, "Field not named");
601 getRAnglebracket(in
);
603 f
->description
= getDescription(in
);
605 f
->description
= NULL
;
609 getLAnglebracket(in
);
610 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
613 getLAnglebracket(in
);
616 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
617 getRAnglebracket(in
); //</field>
622 /*****************************************************************************
624 * parseType : get type information, type can be :
626 * int(size,fmt); uint(size,fmt); float(size,fmt);
627 * string(fmt); enum(size,fmt,(label1,label2...))
629 * array(arraySize, type); sequence(lengthSize,type)
630 * struct(field(name,type,description)...)
634 * in : input file handle
635 * inType : a type descriptor
636 * unnamed_types : array of unamed types
637 * named_types : array of named types
639 * type_descriptor* : a type descriptor
640 ****************************************************************************/
642 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
643 sequence_t
* unnamed_types
, table_t
* named_types
)
646 type_descriptor_t
*t
;
650 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
654 sequence_push(unnamed_types
,t
);
660 if(strcmp(token
,"struct") == 0) {
662 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
663 getRAnglebracket(in
); //<struct>
664 getLAnglebracket(in
); //<field name=..>
665 token
= getToken(in
);
666 sequence_init(&(t
->fields
));
667 while(strcmp("field",token
) == 0){
668 f
= (field_t
*)memAlloc(sizeof(field_t
));
669 sequence_push(&(t
->fields
),f
);
671 parseFields(in
, f
, unnamed_types
, named_types
, 1);
674 getLAnglebracket(in
);
675 token
= getToken(in
);
677 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
679 if(strcmp("struct",token
)!=0)
680 in
->error(in
,"not a valid structure definition");
681 getRAnglebracket(in
); //</struct>
683 else if(strcmp(token
,"union") == 0) {
685 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
686 getRAnglebracket(in
); //<union>
688 getLAnglebracket(in
); //<field name=..>
689 token
= getToken(in
);
690 sequence_init(&(t
->fields
));
691 while(strcmp("field",token
) == 0){
692 f
= (field_t
*)memAlloc(sizeof(field_t
));
693 sequence_push(&(t
->fields
),f
);
694 parseFields(in
, f
, unnamed_types
, named_types
, 1);
697 getLAnglebracket(in
);
698 token
= getToken(in
);
700 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
702 if(strcmp("union",token
)!=0)
703 in
->error(in
,"not a valid union definition");
704 getRAnglebracket(in
); //</union>
706 else if(strcmp(token
,"array") == 0) {
708 sequence_init(&(t
->fields
));
709 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
710 if(t
->size
== 0) in
->error(in
, "Array has empty size");
712 getRAnglebracket(in
); //<array size=n>
714 //getLAnglebracket(in); //<subtype>
716 f
= (field_t
*)memAlloc(sizeof(field_t
));
717 sequence_push(&(t
->fields
),f
);
718 parseFields(in
, f
, unnamed_types
, named_types
, 0);
720 //getLAnglebracket(in); //<type struct>
721 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
723 getLAnglebracket(in
); //</array>
726 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
727 getRAnglebracket(in
); //</array>
729 else if(strcmp(token
,"sequence") == 0) {
731 sequence_init(&(t
->fields
));
732 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
734 getRAnglebracket(in
); //<sequence>
736 //getLAnglebracket(in); //<sequence size type>
738 f
= (field_t
*)memAlloc(sizeof(field_t
));
739 sequence_push(&(t
->fields
),f
);
740 parseFields(in
, f
, unnamed_types
, named_types
, 0);
742 //getLAnglebracket(in); //<subtype>
744 f
= (field_t
*)memAlloc(sizeof(field_t
));
745 sequence_push(&(t
->fields
),f
);
746 parseFields(in
, f
, unnamed_types
, named_types
, 0);
748 //getLAnglebracket(in); //<type sequence>
749 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
751 //getLAnglebracket(in); //<type sequence>
753 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
755 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
756 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
757 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
767 in
->error(in
, "Wrong length type for sequence");
770 getLAnglebracket(in
); //</sequence>
773 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
774 getRAnglebracket(in
); //</sequence>
776 else if(strcmp(token
,"enum") == 0) {
778 long long value
= -1;
781 sequence_init(&(t
->labels
));
782 sequence_init(&(t
->labels_values
));
783 sequence_init(&(t
->labels_description
));
784 t
->already_printed
= 0;
785 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
786 //if(t->size == 0) in->error(in, "Sequence has empty size");
787 //Mathieu : we fix enum size to target int size. GCC is always like this.
788 //fox copy optimisation.
789 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
791 getRAnglebracket(in
);
793 //<label name=label1 value=n/>
794 getLAnglebracket(in
);
795 token
= getToken(in
); //"label" or "/"
796 while(strcmp("label",token
) == 0){
797 int *label_value
= malloc(sizeof(int));
801 str
= allocAndCopy(getNameAttribute(in
));
802 has_value
= getValueAttribute(in
, &loc_value
);
804 sequence_push(&(t
->labels
),str
);
806 if(has_value
) value
= loc_value
;
809 *label_value
= value
;
810 sequence_push(&(t
->labels_values
), label_value
);
813 getRAnglebracket(in
);
815 //read description if any. May be NULL.
816 str
= allocAndCopy(getDescription(in
));
817 sequence_push(&(t
->labels_description
),str
);
819 //next label definition
820 getLAnglebracket(in
);
821 token
= getToken(in
); //"label" or "/"
823 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
825 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
826 getRAnglebracket(in
); //</label>
828 else if(strcmp(token
,"int_fixed") == 0) {
830 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
831 if(t
->size
== 0) in
->error(in
, "int has empty size");
833 getRAnglebracket(in
);
835 else if(strcmp(token
,"uint_fixed") == 0) {
836 t
->type
= UINT_FIXED
;
837 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
838 if(t
->size
== 0) in
->error(in
, "uint has empty size");
840 getRAnglebracket(in
);
842 else if(strcmp(token
,"char") == 0) {
844 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
847 getRAnglebracket(in
);
849 else if(strcmp(token
,"uchar") == 0) {
851 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
854 getRAnglebracket(in
);
856 else if(strcmp(token
,"short") == 0) {
858 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
861 getRAnglebracket(in
);
863 else if(strcmp(token
,"ushort") == 0) {
865 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
868 getRAnglebracket(in
);
870 else if(strcmp(token
,"int") == 0) {
872 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
874 getRAnglebracket(in
);
876 else if(strcmp(token
,"uint") == 0) {
878 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
880 getRAnglebracket(in
);
883 else if(strcmp(token
,"pointer") == 0) {
885 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
887 getRAnglebracket(in
);
889 else if(strcmp(token
,"long") == 0) {
891 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
893 getRAnglebracket(in
);
895 else if(strcmp(token
,"ulong") == 0) {
897 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
899 getRAnglebracket(in
);
901 else if(strcmp(token
,"size_t") == 0) {
903 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
905 getRAnglebracket(in
);
907 else if(strcmp(token
,"ssize_t") == 0) {
909 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
911 getRAnglebracket(in
);
913 else if(strcmp(token
,"off_t") == 0) {
915 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
917 getRAnglebracket(in
);
919 else if(strcmp(token
,"float") == 0) {
921 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
923 getRAnglebracket(in
);
925 else if(strcmp(token
,"string") == 0) {
927 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
929 getRAnglebracket(in
);
931 else if(strcmp(token
,"typeref") == 0){
932 // Must be a named type
934 sequence_pop(unnamed_types
);
935 token
= getNameAttribute(in
);
936 t
= find_named_type(token
, named_types
);
937 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
938 getForwardslash(in
); //<typeref name=type_name/>
939 getRAnglebracket(in
);
941 }else in
->error(in
,"not a valid type");
946 /*****************************************************************************
948 * find_named_type : find a named type from hash table
951 * named_types : array of named types
953 * type_descriptor * : a type descriptor
954 *****************************************************************************/
956 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
958 type_descriptor_t
*t
;
960 t
= table_find(named_types
,name
);
965 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
967 type_descriptor_t
*t
;
969 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
970 t
->type_name
= allocAndCopy(name
);
973 table_insert(named_types
,t
->type_name
,t
);
974 // table_insert(named_types,allocAndCopy(name),t);
978 /*****************************************************************************
980 * parseTypeDefinition : get type information from type definition
982 * in : input file handle
983 * unnamed_types : array of unamed types
984 * named_types : array of named types
985 *****************************************************************************/
987 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
988 table_t
* named_types
)
991 type_descriptor_t
*t
;
993 token
= getNameAttribute(in
);
994 if(token
== NULL
) in
->error(in
, "Type has empty name");
995 t
= create_named_type(token
, named_types
);
997 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
998 getRAnglebracket(in
); //<type name=type_name>
999 getLAnglebracket(in
); //<
1000 token
= getName(in
);
1001 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
1003 parseType(in
,t
, unnamed_types
, named_types
);
1006 getLAnglebracket(in
);
1007 getForwardslash(in
);
1008 token
= getName(in
);
1009 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
1010 getRAnglebracket(in
); //</type>
1013 /**************************************************************************
1015 * getComa, getName, getNumber, getEqual
1017 * Read a token from the input file, check its type, return it scontent.
1020 * in , input file handle.
1023 * address of token content.
1025 **************************************************************************/
1027 char *getName(parse_file_t
* in
)
1031 token
= getToken(in
);
1032 // Optional descriptions
1033 // if(in->type != NAME) in->error(in,"Name token was expected");
1037 int getNumber(parse_file_t
* in
)
1041 token
= getToken(in
);
1042 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
1046 char *getForwardslash(parse_file_t
* in
)
1050 token
= getToken(in
);
1051 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1052 /* Mathieu : final / is optional now. */
1053 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1058 char *getLAnglebracket(parse_file_t
* in
)
1062 token
= getToken(in
);
1063 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1067 char *getRAnglebracket(parse_file_t
* in
)
1071 token
= getToken(in
);
1072 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1076 char *getQuotedString(parse_file_t
* in
)
1080 token
= getToken(in
);
1081 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1085 char * getEqual(parse_file_t
*in
)
1089 token
= getToken(in
);
1090 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1094 char seekNextChar(parse_file_t
*in
)
1097 while((car
= getc(in
->fp
)) != EOF
) {
1106 /******************************************************************
1108 * getToken, ungetToken
1110 * Read a token from the input file and return its type and content.
1111 * Line numbers are accounted for and whitespace/comments are skipped.
1114 * in, input file handle.
1117 * address of token content.
1119 ******************************************************************/
1121 void ungetToken(parse_file_t
* in
)
1126 char *getToken(parse_file_t
* in
)
1130 int pos
= 0, escaped
;
1132 if(in
->unget
== 1) {
1137 /* skip whitespace and comments */
1139 while((car
= getc(fp
)) != EOF
) {
1142 if(car1
== '*') skipComment(in
);
1143 else if(car1
== '/') skipEOL(in
);
1145 car1
= ungetc(car1
,fp
);
1149 else if(car
== '\n') in
->lineno
++;
1150 else if(!isspace(car
)) break;
1158 in
->type
= FORWARDSLASH
;
1159 in
->buffer
[pos
] = car
;
1163 in
->type
= LANGLEBRACKET
;
1164 in
->buffer
[pos
] = car
;
1168 in
->type
= RANGLEBRACKET
;
1169 in
->buffer
[pos
] = car
;
1174 in
->buffer
[pos
] = car
;
1179 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1180 if(car
== '\\' && escaped
== 0) {
1181 in
->buffer
[pos
] = car
;
1186 if(car
== '"' && escaped
== 0) break;
1187 if(car
== '\n' && escaped
== 0) {
1188 in
->error(in
, "non escaped newline inside quoted string");
1190 if(car
== '\n') in
->lineno
++;
1191 in
->buffer
[pos
] = car
;
1195 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1196 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1197 in
->type
= QUOTEDSTRING
;
1201 in
->buffer
[pos
] = car
;
1203 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1208 in
->buffer
[pos
] = car
;
1211 if(car
== EOF
) ungetc(car
,fp
);
1212 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1215 else if(isalnum(car
) || car
== '_' || car
== '-') {
1216 in
->buffer
[0] = car
;
1218 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1219 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1223 in
->buffer
[pos
] = car
;
1226 if(car
== EOF
) ungetc(car
,fp
);
1227 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1230 else in
->error(in
, "invalid character, unrecognized token");
1232 in
->buffer
[pos
] = 0;
1236 void skipComment(parse_file_t
* in
)
1239 while((car
= getc(in
->fp
)) != EOF
) {
1240 if(car
== '\n') in
->lineno
++;
1241 else if(car
== '*') {
1243 if(car
==EOF
) break;
1244 if(car
== '/') return;
1248 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1251 void skipEOL(parse_file_t
* in
)
1254 while((car
= getc(in
->fp
)) != EOF
) {
1260 if(car
== EOF
)ungetc(car
, in
->fp
);
1263 /*****************************************************************************
1265 * checkNamedTypesImplemented : check if all named types have definition
1266 ****************************************************************************/
1268 void checkNamedTypesImplemented(table_t
* named_types
)
1270 type_descriptor_t
*t
;
1274 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1275 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1276 if(t
->type
== NONE
){
1277 sprintf(str
,"named type '%s' has no definition",
1278 (char*)named_types
->keys
.array
[pos
]);
1279 error_callback(NULL
,str
);
1285 /*****************************************************************************
1287 * generateChecksum : generate checksum for the facility
1289 * facName : name of facility
1291 * checksum : checksum for the facility
1292 ****************************************************************************/
1294 void generateChecksum(char* facName
,
1295 unsigned int * checksum
, sequence_t
* events
)
1302 crc
= crc32(facName
);
1303 for(pos
= 0; pos
< events
->position
; pos
++){
1304 ev
= (event_t
*)(events
->array
[pos
]);
1305 crc
= partial_crc32(ev
->name
, crc
);
1306 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1307 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1308 crc
= partial_crc32(f
->name
, crc
);
1309 crc
= getTypeChecksum(crc
, f
->type
);
1315 /*****************************************************************************
1317 * getTypeChecksum : generate checksum by type info
1319 * crc : checksum generated so far
1320 * type : type descriptor containing type info
1322 * unsigned long : checksum
1323 *****************************************************************************/
1325 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1327 unsigned long crc
= aCrc
;
1328 char * str
= NULL
, buf
[16];
1334 str
= intOutputTypes
[getSizeindex(type
->size
)];
1337 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1340 str
= allocAndCopy("void *");
1344 str
= allocAndCopy("signed char");
1348 str
= allocAndCopy("unsigned char");
1352 str
= allocAndCopy("short");
1356 str
= allocAndCopy("unsigned short");
1360 str
= allocAndCopy("int");
1364 str
= allocAndCopy("uint");
1368 str
= allocAndCopy("long");
1372 str
= allocAndCopy("unsigned long");
1376 str
= allocAndCopy("size_t");
1380 str
= allocAndCopy("ssize_t");
1384 str
= allocAndCopy("off_t");
1388 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1391 str
= allocAndCopy("string");
1395 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1396 str
= allocAndCopy("enum");
1400 sprintf(buf
,"%zu", type
->size
);
1401 str
= appendString("array ",buf
);
1405 str
= allocAndCopy("sequence ");
1409 str
= allocAndCopy("struct");
1413 str
= allocAndCopy("union");
1417 error_callback(NULL
, "named type has no definition");
1421 crc
= partial_crc32(str
,crc
);
1424 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1426 if(type
->type
== ARRAY
){
1427 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1428 } else if(type
->type
==SEQUENCE
) {
1429 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1430 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1431 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1432 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1433 fld
= (field_t
*) type
->fields
.array
[pos
];
1434 crc
= partial_crc32(fld
->name
,crc
);
1435 crc
= getTypeChecksum(crc
, fld
->type
);
1437 }else if(type
->type
== ENUM
){
1438 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1439 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1446 /* Event type descriptors */
1447 void freeType(type_descriptor_t
* tp
)
1452 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1453 if(tp
->type
== ENUM
) {
1454 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1455 free(tp
->labels
.array
[pos2
]);
1457 sequence_dispose(&(tp
->labels
));
1458 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1459 free(tp
->labels_values
.array
[pos2
]);
1461 sequence_dispose(&(tp
->labels_values
));
1463 if(tp
->type
== STRUCT
) {
1464 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1465 f
= (field_t
*) tp
->fields
.array
[pos2
];
1467 free(f
->description
);
1470 sequence_dispose(&(tp
->fields
));
1474 void freeNamedType(table_t
* t
)
1477 type_descriptor_t
* td
;
1479 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1480 free((char *)t
->keys
.array
[pos
]);
1481 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1487 void freeTypes(sequence_t
*t
)
1490 type_descriptor_t
*tp
;
1492 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1493 tp
= (type_descriptor_t
*)t
->array
[pos
];
1499 void freeEvents(sequence_t
*t
)
1504 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1505 ev
= (event_t
*) t
->array
[pos
];
1507 free(ev
->description
);
1508 sequence_dispose(&ev
->fields
);
1515 /* Extensible array */
1517 void sequence_init(sequence_t
*t
)
1521 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1524 void sequence_dispose(sequence_t
*t
)
1531 void sequence_push(sequence_t
*t
, void *elem
)
1535 if(t
->position
>= t
->size
) {
1537 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1538 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1539 t
->size
= t
->size
* 2;
1542 t
->array
[t
->position
] = elem
;
1546 void *sequence_pop(sequence_t
*t
)
1548 if(t
->position
== 0) printf("Error : trying to pop an empty sequence");
1549 return t
->array
[--t
->position
];
1553 /* Hash table API, implementation is just linear search for now */
1555 void table_init(table_t
*t
)
1557 sequence_init(&(t
->keys
));
1558 sequence_init(&(t
->values
));
1561 void table_dispose(table_t
*t
)
1563 sequence_dispose(&(t
->keys
));
1564 sequence_dispose(&(t
->values
));
1567 void table_insert(table_t
*t
, char *key
, void *value
)
1569 sequence_push(&(t
->keys
),key
);
1570 sequence_push(&(t
->values
),value
);
1573 void *table_find(table_t
*t
, char *key
)
1576 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1577 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1578 return(t
->values
.array
[pos
]);
1583 void table_insert_int(table_t
*t
, int *key
, void *value
)
1585 sequence_push(&(t
->keys
),key
);
1586 sequence_push(&(t
->values
),value
);
1589 void *table_find_int(table_t
*t
, int *key
)
1592 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1593 if(*key
== *(int *)t
->keys
.array
[pos
])
1594 return(t
->values
.array
[pos
]);
1600 /* Concatenate strings */
1602 char *appendString(char *s
, char *suffix
)
1605 if(suffix
== NULL
) return s
;
1607 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.123828 seconds and 4 git commands to generate.