2 * parser.c: Generate helper declarations and functions to trace events
3 * from an event description file.
5 * Copyright (C) 2005, Mathieu Desnoyers
6 * Copyright (C) 2002, Xianxiu Yang
7 * Copyright (C) 2002, Michel Dagenais
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License Version 2.1 as published by the Free Software Foundation.
13 * This library 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 GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 /* This program reads the ".xml" event definitions input files
25 and constructs structure for each event.
27 The program uses a very simple tokenizer, called from a hand written
28 recursive descent parser to fill a data structure describing the events.
29 The result is a sequence of events definitions which refer to type
32 A table of named types is maintained to allow refering to types by name
33 when the same type is used at several places. Finally a sequence of
34 all types is maintained to facilitate the freeing of all type
35 information when the processing of an ".xml" file is finished. */
41 #include <linux/errno.h>
48 char *intOutputTypes
[] = {
49 "int8_t", "int16_t", "int32_t", "int64_t" };
51 char *uintOutputTypes
[] = {
52 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
54 char *floatOutputTypes
[] = {
55 "undef", "undef", "float", "double" };
61 void strupper(char *string
)
72 int getSizeindex(unsigned int value
)
84 printf("Error : unknown value size %d\n", value
);
89 /*****************************************************************************
91 * getSize : translate from string to integer
93 * in : input file handle
96 *****************************************************************************/
98 unsigned long long int getSize(parse_file_t
*in
)
102 token
= getToken(in
);
103 if(in
->type
== NUMBER
) {
104 return strtoull(token
, NULL
, 0);
106 in
->error(in
,"incorrect size specification");
110 /*****************************************************************************
112 * error_callback : print out error info
114 * in : input file handle
115 * msg : message to be printed
116 ****************************************************************************/
118 void error_callback(parse_file_t
*in
, char *msg
)
121 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
128 /*****************************************************************************
130 * memAlloc : allocate memory
132 * size : required memory size
134 * void * : pointer to allocate memory or NULL
135 ****************************************************************************/
137 void * memAlloc(int size
)
140 if(size
== 0) return NULL
;
143 printf("Failed to allocate memory");
149 /*****************************************************************************
151 * allocAndCopy : allocate memory and initialize it
153 * str : string to be put in memory
155 * char * : pointer to allocate memory or NULL
156 ****************************************************************************/
158 char *allocAndCopy(char *str
)
161 if(str
== NULL
) return NULL
;
162 addr
= (char *)memAlloc(strlen(str
)+1);
167 /**************************************************************************
171 * Read the attribute from the input file.
174 * in , input file handle.
175 * t , the type descriptor to fill.
177 **************************************************************************/
179 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
180 sequence_t
* unnamed_types
, table_t
* named_types
)
189 token
= getToken(in
);
190 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
195 if(!strcmp("format",token
)) {
197 t
->fmt
= allocAndCopy(getQuotedString(in
));
198 //} else if(!strcmp("name",token)) {
200 // car = seekNextChar(in);
201 // if(car == EOF) in->error(in,"name was expected");
202 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
203 // else t->type_name = allocAndCopy(getName(in));
204 } else if(!strcmp("size",token
)) {
206 t
->size
= getSize(in
);
207 } else if(!strcmp("custom_write", token
)) {
213 /**************************************************************************
217 * Read the attribute from the input file.
220 * in , input file handle.
221 * ev , the event to fill.
223 **************************************************************************/
225 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
232 ev
->per_tracefile
= 0;
235 token
= getToken(in
);
236 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
241 if(!strcmp("name",token
)) {
243 car
= seekNextChar(in
);
244 if(car
== EOF
) in
->error(in
,"name was expected");
245 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
246 else ev
->name
= allocAndCopy(getName(in
));
247 } else if(!strcmp("per_trace", token
)) {
249 } else if(!strcmp("per_tracefile", token
)) {
250 ev
->per_tracefile
= 1;
256 /**************************************************************************
258 * getFacilityAttributes
260 * Read the attribute from the input file.
263 * in , input file handle.
264 * fac , the facility to fill.
266 **************************************************************************/
268 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
277 token
= getToken(in
);
278 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
283 if(!strcmp("name",token
)) {
285 car
= seekNextChar(in
);
286 if(car
== EOF
) in
->error(in
,"name was expected");
287 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
288 else fac
->name
= allocAndCopy(getName(in
));
289 } else if(!strcmp("arch", token
)) {
291 car
= seekNextChar(in
);
292 if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
293 else fac
->arch
= allocAndCopy(getName(in
));
298 /**************************************************************************
302 * Read the attribute from the input file.
305 * in , input file handle.
306 * f , the field to fill.
308 **************************************************************************/
310 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
318 token
= getToken(in
);
319 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
324 if(!strcmp("name",token
)) {
326 car
= seekNextChar(in
);
327 if(car
== EOF
) in
->error(in
,"name was expected");
328 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
329 else f
->name
= allocAndCopy(getName(in
));
334 char *getNameAttribute(parse_file_t
*in
)
341 token
= getToken(in
);
342 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
347 if(!strcmp("name",token
)) {
349 car
= seekNextChar(in
);
350 if(car
== EOF
) in
->error(in
,"name was expected");
351 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
352 else name
= allocAndCopy(getName(in
));
355 if(name
== NULL
) in
->error(in
, "Name was expected");
362 //for <label name=label_name value=n format="..."/>, value is an option
363 char * getValueStrAttribute(parse_file_t
*in
)
367 token
= getToken(in
);
368 if(strcmp("/",token
) == 0){
373 if(strcmp("value",token
))in
->error(in
,"value was expected");
375 token
= getToken(in
);
376 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
380 char * getDescription(parse_file_t
*in
)
383 char * token
, car
, *str
;
387 getLAnglebracket(in
);
389 if(strcmp("description",token
)){
390 fseek(in
->fp
, pos
, SEEK_SET
);
394 getRAnglebracket(in
);
397 while((car
= getc(in
->fp
)) != EOF
) {
398 if(car
== '<') break;
399 if(car
== '\0') continue;
400 in
->buffer
[pos
] = car
;
403 if(car
== EOF
)in
->error(in
,"not a valid description");
404 in
->buffer
[pos
] = '\0';
406 str
= allocAndCopy(in
->buffer
);
410 if(strcmp("description", token
))in
->error(in
,"not a valid description");
411 getRAnglebracket(in
);
416 /*****************************************************************************
418 * parseFacility : generate event list
420 * in : input file handle
421 * fac : empty facility
423 * fac : facility filled with event list
424 ****************************************************************************/
426 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
431 getFacilityAttributes(in
, fac
);
432 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
434 fac
->capname
= allocAndCopy(fac
->name
);
435 strupper(fac
->capname
);
436 getRAnglebracket(in
);
438 fac
->description
= getDescription(in
);
441 getLAnglebracket(in
);
443 token
= getToken(in
);
444 if(in
->type
== ENDFILE
)
445 in
->error(in
,"the definition of the facility is not finished");
447 if(strcmp("event",token
) == 0){
448 ev
= (event_t
*) memAlloc(sizeof(event_t
));
449 sequence_push(&(fac
->events
),ev
);
450 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
451 }else if(strcmp("type",token
) == 0){
452 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
453 }else if(in
->type
== FORWARDSLASH
){
455 }else in
->error(in
,"event or type token expected\n");
459 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
460 getRAnglebracket(in
); //</facility>
463 /*****************************************************************************
465 * parseEvent : generate event from event definition
467 * in : input file handle
469 * unnamed_types : array of unamed types
470 * named_types : array of named types
472 * ev : new event (parameters are passed to it)
473 ****************************************************************************/
475 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
476 table_t
* named_types
)
481 sequence_init(&(ev
->fields
));
482 //<event name=eventtype_name>
483 getEventAttributes(in
, ev
);
484 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
485 getRAnglebracket(in
);
487 //<description>...</description>
488 ev
->description
= getDescription(in
);
491 /* Events can have multiple fields. each field form at least a function
492 * parameter of the logging function. */
494 getLAnglebracket(in
);
495 token
= getToken(in
);
498 case FORWARDSLASH
: /* </event> */
500 if(strcmp("event",token
))in
->error(in
,"not an event definition");
501 getRAnglebracket(in
); //</event>
504 case NAME
: /* a field */
505 if(strcmp("field",token
))in
->error(in
,"expecting a field");
506 f
= (field_t
*)memAlloc(sizeof(field_t
));
507 sequence_push(&(ev
->fields
),f
);
508 parseFields(in
, f
, unnamed_types
, named_types
, 1);
511 in
->error(in
, "expecting </event> or <field >");
516 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
518 }else if(in
->type
== NAME
){
519 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
521 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
522 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
523 in
->error(in
,"type must be a struct");
524 }else in
->error(in
, "not a valid type");
526 getLAnglebracket(in
);
528 }else in
->error(in
,"not a struct type");
529 getLAnglebracket(in
);
532 if(strcmp("event",token
))in
->error(in
,"not an event definition");
533 getRAnglebracket(in
); //</event>
537 /*****************************************************************************
539 * parseField : get field infomation from buffer
541 * in : input file handle
543 * unnamed_types : array of unamed types
544 * named_types : array of named types
545 * tag : is field surrounded by a <field> </field> tag ?
546 ****************************************************************************/
548 void parseFields(parse_file_t
*in
, field_t
*f
,
549 sequence_t
* unnamed_types
,
550 table_t
* named_types
,
555 //<field name=field_name> <description> <type> </field>
556 getFieldAttributes(in
, f
);
557 if(f
->name
== NULL
) in
->error(in
, "Field not named");
558 getRAnglebracket(in
);
560 f
->description
= getDescription(in
);
564 getLAnglebracket(in
);
565 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
568 getLAnglebracket(in
);
571 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
572 getRAnglebracket(in
); //</field>
577 /*****************************************************************************
579 * parseType : get type information, type can be :
581 * int(size,fmt); uint(size,fmt); float(size,fmt);
582 * string(fmt); enum(size,fmt,(label1,label2...))
584 * array(arraySize, type); sequence(lengthSize,type)
585 * struct(field(name,type,description)...)
589 * in : input file handle
590 * inType : a type descriptor
591 * unnamed_types : array of unamed types
592 * named_types : array of named types
594 * type_descriptor* : a type descriptor
595 ****************************************************************************/
597 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
598 sequence_t
* unnamed_types
, table_t
* named_types
)
601 type_descriptor_t
*t
;
605 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
609 sequence_push(unnamed_types
,t
);
615 if(strcmp(token
,"struct") == 0) {
617 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
618 getRAnglebracket(in
); //<struct>
619 getLAnglebracket(in
); //<field name=..>
620 token
= getToken(in
);
621 sequence_init(&(t
->fields
));
622 while(strcmp("field",token
) == 0){
623 f
= (field_t
*)memAlloc(sizeof(field_t
));
624 sequence_push(&(t
->fields
),f
);
626 parseFields(in
, f
, unnamed_types
, named_types
, 1);
629 getLAnglebracket(in
);
630 token
= getToken(in
);
632 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
634 if(strcmp("struct",token
)!=0)
635 in
->error(in
,"not a valid structure definition");
636 getRAnglebracket(in
); //</struct>
638 else if(strcmp(token
,"union") == 0) {
640 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
641 getRAnglebracket(in
); //<union>
643 getLAnglebracket(in
); //<field name=..>
644 token
= getToken(in
);
645 sequence_init(&(t
->fields
));
646 while(strcmp("field",token
) == 0){
647 f
= (field_t
*)memAlloc(sizeof(field_t
));
648 sequence_push(&(t
->fields
),f
);
649 parseFields(in
, f
, unnamed_types
, named_types
, 1);
652 getLAnglebracket(in
);
653 token
= getToken(in
);
655 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
657 if(strcmp("union",token
)!=0)
658 in
->error(in
,"not a valid union definition");
659 getRAnglebracket(in
); //</union>
661 else if(strcmp(token
,"array") == 0) {
663 sequence_init(&(t
->fields
));
664 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
665 if(t
->size
== 0) in
->error(in
, "Array has empty size");
667 getRAnglebracket(in
); //<array size=n>
669 //getLAnglebracket(in); //<subtype>
671 f
= (field_t
*)memAlloc(sizeof(field_t
));
672 sequence_push(&(t
->fields
),f
);
673 parseFields(in
, f
, unnamed_types
, named_types
, 0);
675 //getLAnglebracket(in); //<type struct>
676 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
678 getLAnglebracket(in
); //</array>
681 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
682 getRAnglebracket(in
); //</array>
684 else if(strcmp(token
,"sequence") == 0) {
686 sequence_init(&(t
->fields
));
687 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
689 getRAnglebracket(in
); //<sequence>
691 //getLAnglebracket(in); //<sequence size type>
693 f
= (field_t
*)memAlloc(sizeof(field_t
));
694 sequence_push(&(t
->fields
),f
);
695 parseFields(in
, f
, unnamed_types
, named_types
, 0);
697 //getLAnglebracket(in); //<subtype>
699 f
= (field_t
*)memAlloc(sizeof(field_t
));
700 sequence_push(&(t
->fields
),f
);
701 parseFields(in
, f
, unnamed_types
, named_types
, 0);
703 //getLAnglebracket(in); //<type sequence>
704 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
706 //getLAnglebracket(in); //<type sequence>
708 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
710 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
711 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
712 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
722 in
->error(in
, "Wrong length type for sequence");
725 getLAnglebracket(in
); //</sequence>
728 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
729 getRAnglebracket(in
); //</sequence>
731 else if(strcmp(token
,"enum") == 0) {
736 sequence_init(&(t
->labels
));
737 sequence_init(&(t
->labels_values
));
738 sequence_init(&(t
->labels_description
));
739 t
->already_printed
= 0;
740 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
741 //if(t->size == 0) in->error(in, "Sequence has empty size");
742 //Mathieu : we fix enum size to target int size. GCC is always like this.
743 //fox copy optimisation.
744 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
746 getRAnglebracket(in
);
748 //<label name=label1 value=n/>
749 getLAnglebracket(in
);
750 token
= getToken(in
); //"label" or "/"
751 while(strcmp("label",token
) == 0){
752 int *label_value
= malloc(sizeof(int));
754 str
= allocAndCopy(getNameAttribute(in
));
755 token
= getValueStrAttribute(in
);
757 sequence_push(&(t
->labels
),str
);
759 if(token
) value
= strtol(token
, NULL
, 0);
762 *label_value
= value
;
763 sequence_push(&(t
->labels_values
), label_value
);
766 getRAnglebracket(in
);
768 //read description if any. May be NULL.
769 str
= allocAndCopy(getDescription(in
));
770 sequence_push(&(t
->labels_description
),str
);
772 //next label definition
773 getLAnglebracket(in
);
774 token
= getToken(in
); //"label" or "/"
776 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
778 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
779 getRAnglebracket(in
); //</label>
781 else if(strcmp(token
,"int_fixed") == 0) {
783 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
784 if(t
->size
== 0) in
->error(in
, "int has empty size");
786 getRAnglebracket(in
);
788 else if(strcmp(token
,"uint_fixed") == 0) {
789 t
->type
= UINT_FIXED
;
790 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
791 if(t
->size
== 0) in
->error(in
, "uint has empty size");
793 getRAnglebracket(in
);
795 else if(strcmp(token
,"char") == 0) {
797 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
800 getRAnglebracket(in
);
802 else if(strcmp(token
,"uchar") == 0) {
804 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
807 getRAnglebracket(in
);
809 else if(strcmp(token
,"short") == 0) {
811 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
814 getRAnglebracket(in
);
816 else if(strcmp(token
,"ushort") == 0) {
818 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
821 getRAnglebracket(in
);
823 else if(strcmp(token
,"int") == 0) {
825 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
827 getRAnglebracket(in
);
829 else if(strcmp(token
,"uint") == 0) {
831 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
833 getRAnglebracket(in
);
836 else if(strcmp(token
,"pointer") == 0) {
838 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
840 getRAnglebracket(in
);
842 else if(strcmp(token
,"long") == 0) {
844 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
846 getRAnglebracket(in
);
848 else if(strcmp(token
,"ulong") == 0) {
850 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
852 getRAnglebracket(in
);
854 else if(strcmp(token
,"size_t") == 0) {
856 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
858 getRAnglebracket(in
);
860 else if(strcmp(token
,"ssize_t") == 0) {
862 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
864 getRAnglebracket(in
);
866 else if(strcmp(token
,"off_t") == 0) {
868 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
870 getRAnglebracket(in
);
872 else if(strcmp(token
,"float") == 0) {
874 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
876 getRAnglebracket(in
);
878 else if(strcmp(token
,"string") == 0) {
880 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
882 getRAnglebracket(in
);
884 else if(strcmp(token
,"typeref") == 0){
885 // Must be a named type
887 sequence_pop(unnamed_types
);
888 token
= getNameAttribute(in
);
889 t
= find_named_type(token
, named_types
);
890 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
891 getForwardslash(in
); //<typeref name=type_name/>
892 getRAnglebracket(in
);
894 }else in
->error(in
,"not a valid type");
899 /*****************************************************************************
901 * find_named_type : find a named type from hash table
904 * named_types : array of named types
906 * type_descriptor * : a type descriptor
907 *****************************************************************************/
909 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
911 type_descriptor_t
*t
;
913 t
= table_find(named_types
,name
);
918 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
920 type_descriptor_t
*t
;
922 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
923 t
->type_name
= allocAndCopy(name
);
926 table_insert(named_types
,t
->type_name
,t
);
927 // table_insert(named_types,allocAndCopy(name),t);
931 /*****************************************************************************
933 * parseTypeDefinition : get type information from type definition
935 * in : input file handle
936 * unnamed_types : array of unamed types
937 * named_types : array of named types
938 *****************************************************************************/
940 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
941 table_t
* named_types
)
944 type_descriptor_t
*t
;
946 token
= getNameAttribute(in
);
947 if(token
== NULL
) in
->error(in
, "Type has empty name");
948 t
= create_named_type(token
, named_types
);
950 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
951 getRAnglebracket(in
); //<type name=type_name>
952 getLAnglebracket(in
); //<
954 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
956 parseType(in
,t
, unnamed_types
, named_types
);
959 getLAnglebracket(in
);
962 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
963 getRAnglebracket(in
); //</type>
966 /**************************************************************************
968 * getComa, getName, getNumber, getEqual
970 * Read a token from the input file, check its type, return it scontent.
973 * in , input file handle.
976 * address of token content.
978 **************************************************************************/
980 char *getName(parse_file_t
* in
)
984 token
= getToken(in
);
985 // Optional descriptions
986 // if(in->type != NAME) in->error(in,"Name token was expected");
990 int getNumber(parse_file_t
* in
)
994 token
= getToken(in
);
995 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
999 char *getForwardslash(parse_file_t
* in
)
1003 token
= getToken(in
);
1004 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1005 /* Mathieu : final / is optional now. */
1006 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1011 char *getLAnglebracket(parse_file_t
* in
)
1015 token
= getToken(in
);
1016 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1020 char *getRAnglebracket(parse_file_t
* in
)
1024 token
= getToken(in
);
1025 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1029 char *getQuotedString(parse_file_t
* in
)
1033 token
= getToken(in
);
1034 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1038 char * getEqual(parse_file_t
*in
)
1042 token
= getToken(in
);
1043 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1047 char seekNextChar(parse_file_t
*in
)
1050 while((car
= getc(in
->fp
)) != EOF
) {
1059 /******************************************************************
1061 * getToken, ungetToken
1063 * Read a token from the input file and return its type and content.
1064 * Line numbers are accounted for and whitespace/comments are skipped.
1067 * in, input file handle.
1070 * address of token content.
1072 ******************************************************************/
1074 void ungetToken(parse_file_t
* in
)
1079 char *getToken(parse_file_t
* in
)
1083 int pos
= 0, escaped
;
1085 if(in
->unget
== 1) {
1090 /* skip whitespace and comments */
1092 while((car
= getc(fp
)) != EOF
) {
1095 if(car1
== '*') skipComment(in
);
1096 else if(car1
== '/') skipEOL(in
);
1098 car1
= ungetc(car1
,fp
);
1102 else if(car
== '\n') in
->lineno
++;
1103 else if(!isspace(car
)) break;
1111 in
->type
= FORWARDSLASH
;
1112 in
->buffer
[pos
] = car
;
1116 in
->type
= LANGLEBRACKET
;
1117 in
->buffer
[pos
] = car
;
1121 in
->type
= RANGLEBRACKET
;
1122 in
->buffer
[pos
] = car
;
1127 in
->buffer
[pos
] = car
;
1132 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1133 if(car
== '\\' && escaped
== 0) {
1134 in
->buffer
[pos
] = car
;
1139 if(car
== '"' && escaped
== 0) break;
1140 if(car
== '\n' && escaped
== 0) {
1141 in
->error(in
, "non escaped newline inside quoted string");
1143 if(car
== '\n') in
->lineno
++;
1144 in
->buffer
[pos
] = car
;
1148 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1149 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1150 in
->type
= QUOTEDSTRING
;
1154 in
->buffer
[pos
] = car
;
1156 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1161 in
->buffer
[pos
] = car
;
1164 if(car
== EOF
) ungetc(car
,fp
);
1165 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1168 else if(isalnum(car
) || car
== '_' || car
== '-') {
1169 in
->buffer
[0] = car
;
1171 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1172 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1176 in
->buffer
[pos
] = car
;
1179 if(car
== EOF
) ungetc(car
,fp
);
1180 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1183 else in
->error(in
, "invalid character, unrecognized token");
1185 in
->buffer
[pos
] = 0;
1189 void skipComment(parse_file_t
* in
)
1192 while((car
= getc(in
->fp
)) != EOF
) {
1193 if(car
== '\n') in
->lineno
++;
1194 else if(car
== '*') {
1196 if(car
==EOF
) break;
1197 if(car
== '/') return;
1201 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1204 void skipEOL(parse_file_t
* in
)
1207 while((car
= getc(in
->fp
)) != EOF
) {
1213 if(car
== EOF
)ungetc(car
, in
->fp
);
1216 /*****************************************************************************
1218 * checkNamedTypesImplemented : check if all named types have definition
1219 ****************************************************************************/
1221 void checkNamedTypesImplemented(table_t
* named_types
)
1223 type_descriptor_t
*t
;
1227 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1228 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1229 if(t
->type
== NONE
){
1230 sprintf(str
,"named type '%s' has no definition",
1231 (char*)named_types
->keys
.array
[pos
]);
1232 error_callback(NULL
,str
);
1238 /*****************************************************************************
1240 * generateChecksum : generate checksum for the facility
1242 * facName : name of facility
1244 * checksum : checksum for the facility
1245 ****************************************************************************/
1247 void generateChecksum(char* facName
,
1248 unsigned int * checksum
, sequence_t
* events
)
1255 crc
= crc32(facName
);
1256 for(pos
= 0; pos
< events
->position
; pos
++){
1257 ev
= (event_t
*)(events
->array
[pos
]);
1258 crc
= partial_crc32(ev
->name
, crc
);
1259 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1260 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1261 crc
= partial_crc32(f
->name
, crc
);
1262 crc
= getTypeChecksum(crc
, f
->type
);
1268 /*****************************************************************************
1270 * getTypeChecksum : generate checksum by type info
1272 * crc : checksum generated so far
1273 * type : type descriptor containing type info
1275 * unsigned long : checksum
1276 *****************************************************************************/
1278 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1280 unsigned long crc
= aCrc
;
1281 char * str
= NULL
, buf
[16];
1287 str
= intOutputTypes
[getSizeindex(type
->size
)];
1290 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1293 str
= allocAndCopy("void *");
1297 str
= allocAndCopy("signed char");
1301 str
= allocAndCopy("unsigned char");
1305 str
= allocAndCopy("short");
1309 str
= allocAndCopy("unsigned short");
1313 str
= allocAndCopy("int");
1317 str
= allocAndCopy("uint");
1321 str
= allocAndCopy("long");
1325 str
= allocAndCopy("unsigned long");
1329 str
= allocAndCopy("size_t");
1333 str
= allocAndCopy("ssize_t");
1337 str
= allocAndCopy("off_t");
1341 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1344 str
= allocAndCopy("string");
1348 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1349 str
= allocAndCopy("enum");
1353 sprintf(buf
,"%zu", type
->size
);
1354 str
= appendString("array ",buf
);
1358 str
= allocAndCopy("sequence ");
1362 str
= allocAndCopy("struct");
1366 str
= allocAndCopy("union");
1370 error_callback(NULL
, "named type has no definition");
1374 crc
= partial_crc32(str
,crc
);
1377 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1379 if(type
->type
== ARRAY
){
1380 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1381 } else if(type
->type
==SEQUENCE
) {
1382 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1383 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1384 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1385 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1386 fld
= (field_t
*) type
->fields
.array
[pos
];
1387 crc
= partial_crc32(fld
->name
,crc
);
1388 crc
= getTypeChecksum(crc
, fld
->type
);
1390 }else if(type
->type
== ENUM
){
1391 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1392 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1399 /* Event type descriptors */
1400 void freeType(type_descriptor_t
* tp
)
1405 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1406 if(tp
->type
== ENUM
) {
1407 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1408 free(tp
->labels
.array
[pos2
]);
1410 sequence_dispose(&(tp
->labels
));
1411 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1412 free(tp
->labels_values
.array
[pos2
]);
1414 sequence_dispose(&(tp
->labels_values
));
1416 if(tp
->type
== STRUCT
) {
1417 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1418 f
= (field_t
*) tp
->fields
.array
[pos2
];
1420 free(f
->description
);
1423 sequence_dispose(&(tp
->fields
));
1427 void freeNamedType(table_t
* t
)
1430 type_descriptor_t
* td
;
1432 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1433 free((char *)t
->keys
.array
[pos
]);
1434 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1440 void freeTypes(sequence_t
*t
)
1443 type_descriptor_t
*tp
;
1445 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1446 tp
= (type_descriptor_t
*)t
->array
[pos
];
1452 void freeEvents(sequence_t
*t
)
1457 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1458 ev
= (event_t
*) t
->array
[pos
];
1460 free(ev
->description
);
1461 sequence_dispose(&ev
->fields
);
1468 /* Extensible array */
1470 void sequence_init(sequence_t
*t
)
1474 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1477 void sequence_dispose(sequence_t
*t
)
1484 void sequence_push(sequence_t
*t
, void *elem
)
1488 if(t
->position
>= t
->size
) {
1490 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1491 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1492 t
->size
= t
->size
* 2;
1495 t
->array
[t
->position
] = elem
;
1499 void *sequence_pop(sequence_t
*t
)
1501 return t
->array
[t
->position
--];
1505 /* Hash table API, implementation is just linear search for now */
1507 void table_init(table_t
*t
)
1509 sequence_init(&(t
->keys
));
1510 sequence_init(&(t
->values
));
1513 void table_dispose(table_t
*t
)
1515 sequence_dispose(&(t
->keys
));
1516 sequence_dispose(&(t
->values
));
1519 void table_insert(table_t
*t
, char *key
, void *value
)
1521 sequence_push(&(t
->keys
),key
);
1522 sequence_push(&(t
->values
),value
);
1525 void *table_find(table_t
*t
, char *key
)
1528 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1529 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1530 return(t
->values
.array
[pos
]);
1535 void table_insert_int(table_t
*t
, int *key
, void *value
)
1537 sequence_push(&(t
->keys
),key
);
1538 sequence_push(&(t
->values
),value
);
1541 void *table_find_int(table_t
*t
, int *key
)
1544 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1545 if(*key
== *(int *)t
->keys
.array
[pos
])
1546 return(t
->values
.array
[pos
]);
1552 /* Concatenate strings */
1554 char *appendString(char *s
, char *suffix
)
1557 if(suffix
== NULL
) return s
;
1559 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.063719 seconds and 4 git commands to generate.