17ebef72373e87de845e524021e659a0b8e6a21e
3 parser.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* This program reads the ".xml" event definitions input files
23 and constructs structure for each event.
25 The program uses a very simple tokenizer, called from a hand written
26 recursive descent parser to fill a data structure describing the events.
27 The result is a sequence of events definitions which refer to type
30 A table of named types is maintained to allow refering to types by name
31 when the same type is used at several places. Finally a sequence of
32 all types is maintained to facilitate the freeing of all type
33 information when the processing of an ".xml" file is finished. */
39 #include <linux/errno.h>
46 char *intOutputTypes
[] = {
47 "int8_t", "int16_t", "int32_t", "int64_t" };
49 char *uintOutputTypes
[] = {
50 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
52 char *floatOutputTypes
[] = {
53 "undef", "undef", "float", "double" };
59 void strupper(char *string
)
70 int getSizeindex(unsigned int value
)
82 printf("Error : unknown value size %d\n", value
);
87 /*****************************************************************************
89 * getSize : translate from string to integer
91 * in : input file handle
94 *****************************************************************************/
96 unsigned long long int getSize(parse_file_t
*in
)
100 token
= getToken(in
);
101 if(in
->type
== NUMBER
) {
102 return strtoull(token
, NULL
, 0);
104 in
->error(in
,"incorrect size specification");
108 /*****************************************************************************
110 * error_callback : print out error info
112 * in : input file handle
113 * msg : message to be printed
114 ****************************************************************************/
116 void error_callback(parse_file_t
*in
, char *msg
)
119 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
126 /*****************************************************************************
128 * memAlloc : allocate memory
130 * size : required memory size
132 * void * : pointer to allocate memory or NULL
133 ****************************************************************************/
135 void * memAlloc(int size
)
138 if(size
== 0) return NULL
;
141 printf("Failed to allocate memory");
147 /*****************************************************************************
149 * allocAndCopy : allocate memory and initialize it
151 * str : string to be put in memory
153 * char * : pointer to allocate memory or NULL
154 ****************************************************************************/
156 char *allocAndCopy(char *str
)
159 if(str
== NULL
) return NULL
;
160 addr
= (char *)memAlloc(strlen(str
)+1);
165 /**************************************************************************
169 * Read the attribute from the input file.
172 * in , input file handle.
173 * t , the type descriptor to fill.
175 **************************************************************************/
177 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
178 sequence_t
* unnamed_types
, table_t
* named_types
)
187 token
= getToken(in
);
188 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
193 if(!strcmp("format",token
)) {
195 t
->fmt
= allocAndCopy(getQuotedString(in
));
196 //} else if(!strcmp("name",token)) {
198 // car = seekNextChar(in);
199 // if(car == EOF) in->error(in,"name was expected");
200 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
201 // else t->type_name = allocAndCopy(getName(in));
202 } else if(!strcmp("size",token
)) {
204 t
->size
= getSize(in
);
205 } else if(!strcmp("align",token
)) {
207 t
->alignment
= getNumber(in
);
212 /**************************************************************************
216 * Read the attribute from the input file.
219 * in , input file handle.
220 * ev , the event to fill.
222 **************************************************************************/
224 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
231 ev
->per_tracefile
= 0;
234 token
= getToken(in
);
235 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
240 if(!strcmp("name",token
)) {
242 car
= seekNextChar(in
);
243 if(car
== EOF
) in
->error(in
,"name was expected");
244 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
245 else ev
->name
= allocAndCopy(getName(in
));
246 } else if(!strcmp("per_trace", token
)) {
248 } else if(!strcmp("per_tracefile", token
)) {
249 ev
->per_tracefile
= 1;
255 /**************************************************************************
257 * getFacilityAttributes
259 * Read the attribute from the input file.
262 * in , input file handle.
263 * fac , the facility to fill.
265 **************************************************************************/
267 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
275 token
= getToken(in
);
276 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
281 if(!strcmp("name",token
)) {
283 car
= seekNextChar(in
);
284 if(car
== EOF
) in
->error(in
,"name was expected");
285 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
286 else fac
->name
= allocAndCopy(getName(in
));
291 /**************************************************************************
295 * Read the attribute from the input file.
298 * in , input file handle.
299 * f , the field to fill.
301 **************************************************************************/
303 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
311 token
= getToken(in
);
312 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
317 if(!strcmp("name",token
)) {
319 car
= seekNextChar(in
);
320 if(car
== EOF
) in
->error(in
,"name was expected");
321 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
322 else f
->name
= allocAndCopy(getName(in
));
327 char *getNameAttribute(parse_file_t
*in
)
334 token
= getToken(in
);
335 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
340 if(!strcmp("name",token
)) {
342 car
= seekNextChar(in
);
343 if(car
== EOF
) in
->error(in
,"name was expected");
344 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
345 else name
= allocAndCopy(getName(in
));
348 if(name
== NULL
) in
->error(in
, "Name was expected");
355 //for <label name=label_name value=n format="..."/>, value is an option
356 char * getValueStrAttribute(parse_file_t
*in
)
360 token
= getToken(in
);
361 if(strcmp("/",token
) == 0){
366 if(strcmp("value",token
))in
->error(in
,"value was expected");
368 token
= getToken(in
);
369 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
373 char * getDescription(parse_file_t
*in
)
376 char * token
, car
, *str
;
380 getLAnglebracket(in
);
382 if(strcmp("description",token
)){
383 fseek(in
->fp
, pos
, SEEK_SET
);
387 getRAnglebracket(in
);
390 while((car
= getc(in
->fp
)) != EOF
) {
391 if(car
== '<') break;
392 if(car
== '\0') continue;
393 in
->buffer
[pos
] = car
;
396 if(car
== EOF
)in
->error(in
,"not a valid description");
397 in
->buffer
[pos
] = '\0';
399 str
= allocAndCopy(in
->buffer
);
403 if(strcmp("description", token
))in
->error(in
,"not a valid description");
404 getRAnglebracket(in
);
409 /*****************************************************************************
411 * parseFacility : generate event list
413 * in : input file handle
414 * fac : empty facility
416 * fac : facility filled with event list
417 ****************************************************************************/
419 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
424 getFacilityAttributes(in
, fac
);
425 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
427 fac
->capname
= allocAndCopy(fac
->name
);
428 strupper(fac
->capname
);
429 getRAnglebracket(in
);
431 fac
->description
= getDescription(in
);
434 getLAnglebracket(in
);
436 token
= getToken(in
);
437 if(in
->type
== ENDFILE
)
438 in
->error(in
,"the definition of the facility is not finished");
440 if(strcmp("event",token
) == 0){
441 ev
= (event_t
*) memAlloc(sizeof(event_t
));
442 sequence_push(&(fac
->events
),ev
);
443 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
444 }else if(strcmp("type",token
) == 0){
445 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
446 }else if(in
->type
== FORWARDSLASH
){
448 }else in
->error(in
,"event or type token expected\n");
452 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
453 getRAnglebracket(in
); //</facility>
456 /*****************************************************************************
458 * parseEvent : generate event from event definition
460 * in : input file handle
462 * unnamed_types : array of unamed types
463 * named_types : array of named types
465 * ev : new event (parameters are passed to it)
466 ****************************************************************************/
468 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
469 table_t
* named_types
)
474 sequence_init(&(ev
->fields
));
475 //<event name=eventtype_name>
476 getEventAttributes(in
, ev
);
477 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
478 getRAnglebracket(in
);
480 //<description>...</description>
481 ev
->description
= getDescription(in
);
484 /* Events can have multiple fields. each field form at least a function
485 * parameter of the logging function. */
487 getLAnglebracket(in
);
488 token
= getToken(in
);
491 case FORWARDSLASH
: /* </event> */
493 if(strcmp("event",token
))in
->error(in
,"not an event definition");
494 getRAnglebracket(in
); //</event>
497 case NAME
: /* a field */
498 if(strcmp("field",token
))in
->error(in
,"expecting a field");
499 f
= (field_t
*)memAlloc(sizeof(field_t
));
500 sequence_push(&(ev
->fields
),f
);
501 parseFields(in
, f
, unnamed_types
, named_types
);
504 in
->error(in
, "expecting </event> or <field >");
509 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
511 }else if(in
->type
== NAME
){
512 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
514 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
515 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
516 in
->error(in
,"type must be a struct");
517 }else in
->error(in
, "not a valid type");
519 getLAnglebracket(in
);
521 }else in
->error(in
,"not a struct type");
522 getLAnglebracket(in
);
525 if(strcmp("event",token
))in
->error(in
,"not an event definition");
526 getRAnglebracket(in
); //</event>
530 /*****************************************************************************
532 * parseField : get field infomation from buffer
534 * in : input file handle
536 * unnamed_types : array of unamed types
537 * named_types : array of named types
538 ****************************************************************************/
540 void parseFields(parse_file_t
*in
, field_t
*f
,
541 sequence_t
* unnamed_types
,
542 table_t
* named_types
)
546 //<field name=field_name> <description> <type> </field>
547 getFieldAttributes(in
, f
);
548 if(f
->name
== NULL
) in
->error(in
, "Field not named");
549 getRAnglebracket(in
);
551 f
->description
= getDescription(in
);
554 getLAnglebracket(in
);
555 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
557 getLAnglebracket(in
);
560 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
561 getRAnglebracket(in
); //</field>
565 /*****************************************************************************
567 * parseType : get type information, type can be :
569 * int(size,fmt); uint(size,fmt); float(size,fmt);
570 * string(fmt); enum(size,fmt,(label1,label2...))
572 * array(arraySize, type); sequence(lengthSize,type)
573 * struct(field(name,type,description)...)
577 * in : input file handle
578 * inType : a type descriptor
579 * unnamed_types : array of unamed types
580 * named_types : array of named types
582 * type_descriptor* : a type descriptor
583 ****************************************************************************/
585 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
586 sequence_t
* unnamed_types
, table_t
* named_types
)
589 type_descriptor_t
*t
;
593 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
597 sequence_push(unnamed_types
,t
);
603 if(strcmp(token
,"struct") == 0) {
605 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
606 getRAnglebracket(in
); //<struct>
607 getLAnglebracket(in
); //<field name=..>
608 token
= getToken(in
);
609 sequence_init(&(t
->fields
));
610 while(strcmp("field",token
) == 0){
611 f
= (field_t
*)memAlloc(sizeof(field_t
));
612 sequence_push(&(t
->fields
),f
);
614 parseFields(in
, f
, unnamed_types
, named_types
);
617 getLAnglebracket(in
);
618 token
= getToken(in
);
620 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
622 if(strcmp("struct",token
)!=0)
623 in
->error(in
,"not a valid structure definition");
624 getRAnglebracket(in
); //</struct>
626 else if(strcmp(token
,"union") == 0) {
628 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
629 getRAnglebracket(in
); //<union>
631 getLAnglebracket(in
); //<field name=..>
632 token
= getToken(in
);
633 sequence_init(&(t
->fields
));
634 while(strcmp("field",token
) == 0){
635 f
= (field_t
*)memAlloc(sizeof(field_t
));
636 sequence_push(&(t
->fields
),f
);
637 parseFields(in
, f
, unnamed_types
, named_types
);
640 getLAnglebracket(in
);
641 token
= getToken(in
);
643 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
645 if(strcmp("union",token
)!=0)
646 in
->error(in
,"not a valid union definition");
647 getRAnglebracket(in
); //</union>
649 else if(strcmp(token
,"array") == 0) {
651 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
652 if(t
->size
== 0) in
->error(in
, "Array has empty size");
654 getRAnglebracket(in
); //<array size=n>
656 getLAnglebracket(in
); //<type struct>
657 t
->nested_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
659 getLAnglebracket(in
); //</array>
662 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
663 getRAnglebracket(in
); //</array>
665 else if(strcmp(token
,"sequence") == 0) {
667 //getTypeAttributes(in, t, unnamed_types, named_types);
668 //getForwardslash(in);
669 getRAnglebracket(in
); //<sequence>
671 getLAnglebracket(in
); //<type sequence>
672 t
->length_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
674 getLAnglebracket(in
); //<type sequence>
676 t
->nested_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
678 if(t
->length_type
== NULL
) in
->error(in
, "Sequence has no length type");
679 switch(t
->length_type
->type
) {
689 in
->error(in
, "Wrong length type for sequence");
693 if(t
->nested_type
== NULL
) in
->error(in
, "Sequence has no nested type");
694 getLAnglebracket(in
); //</sequence>
697 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
698 getRAnglebracket(in
); //</sequence>
700 else if(strcmp(token
,"enum") == 0) {
703 sequence_init(&(t
->labels
));
704 sequence_init(&(t
->labels_description
));
705 t
->already_printed
= 0;
706 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
707 //if(t->size == 0) in->error(in, "Sequence has empty size");
708 //Mathieu : we fix enum size to 4 bytes. GCC is always like this.
709 //fox copy optimisation.
710 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of 4.");
712 getRAnglebracket(in
);
714 //<label name=label1 value=n/>
715 getLAnglebracket(in
);
716 token
= getToken(in
); //"label" or "/"
717 while(strcmp("label",token
) == 0){
718 str
= allocAndCopy(getNameAttribute(in
));
719 token
= getValueStrAttribute(in
);
721 str1
= appendString(str
,"=");
723 str
= appendString(str1
,token
);
725 sequence_push(&(t
->labels
),str
);
728 sequence_push(&(t
->labels
),str
);
731 getRAnglebracket(in
);
733 //read description if any. May be NULL.
734 str
= allocAndCopy(getDescription(in
));
735 sequence_push(&(t
->labels_description
),str
);
737 //next label definition
738 getLAnglebracket(in
);
739 token
= getToken(in
); //"label" or "/"
741 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
743 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
744 getRAnglebracket(in
); //</label>
746 else if(strcmp(token
,"int_fixed") == 0) {
748 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
749 if(t
->size
== 0) in
->error(in
, "int has empty size");
751 getRAnglebracket(in
);
753 else if(strcmp(token
,"uint_fixed") == 0) {
754 t
->type
= UINT_FIXED
;
755 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
756 if(t
->size
== 0) in
->error(in
, "uint has empty size");
758 getRAnglebracket(in
);
760 else if(strcmp(token
,"char") == 0) {
762 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
764 getRAnglebracket(in
);
766 else if(strcmp(token
,"uchar") == 0) {
768 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
770 getRAnglebracket(in
);
772 else if(strcmp(token
,"short") == 0) {
774 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
776 getRAnglebracket(in
);
778 else if(strcmp(token
,"ushort") == 0) {
780 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
782 getRAnglebracket(in
);
784 else if(strcmp(token
,"int") == 0) {
786 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
788 getRAnglebracket(in
);
790 else if(strcmp(token
,"uint") == 0) {
792 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
794 getRAnglebracket(in
);
797 else if(strcmp(token
,"pointer") == 0) {
799 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
801 getRAnglebracket(in
);
803 else if(strcmp(token
,"long") == 0) {
805 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
807 getRAnglebracket(in
);
809 else if(strcmp(token
,"ulong") == 0) {
811 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
813 getRAnglebracket(in
);
815 else if(strcmp(token
,"size_t") == 0) {
817 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
819 getRAnglebracket(in
);
821 else if(strcmp(token
,"ssize_t") == 0) {
823 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
825 getRAnglebracket(in
);
827 else if(strcmp(token
,"off_t") == 0) {
829 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
831 getRAnglebracket(in
);
833 else if(strcmp(token
,"float") == 0) {
835 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
837 getRAnglebracket(in
);
839 else if(strcmp(token
,"string") == 0) {
841 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
843 getRAnglebracket(in
);
845 else if(strcmp(token
,"typeref") == 0){
846 // Must be a named type
848 in
->error(in
,"Named type cannot refer to a named type");
851 sequence_pop(unnamed_types
);
852 token
= getNameAttribute(in
);
853 t
= find_named_type(token
, named_types
);
854 getForwardslash(in
); //<typeref name=type_name/>
855 getRAnglebracket(in
);
858 }else in
->error(in
,"not a valid type");
863 /*****************************************************************************
865 * find_named_type : find a named type from hash table
868 * named_types : array of named types
870 * type_descriptor * : a type descriptor
871 *****************************************************************************/
873 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
875 type_descriptor_t
*t
;
877 t
= table_find(named_types
,name
);
879 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
880 t
->type_name
= allocAndCopy(name
);
883 table_insert(named_types
,t
->type_name
,t
);
884 // table_insert(named_types,allocAndCopy(name),t);
889 /*****************************************************************************
891 * parseTypeDefinition : get type information from type definition
893 * in : input file handle
894 * unnamed_types : array of unamed types
895 * named_types : array of named types
896 *****************************************************************************/
898 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
899 table_t
* named_types
)
902 type_descriptor_t
*t
;
904 token
= getNameAttribute(in
);
905 if(token
== NULL
) in
->error(in
, "Type has empty name");
906 t
= find_named_type(token
, named_types
);
908 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
909 getRAnglebracket(in
); //<type name=type_name>
910 getLAnglebracket(in
); //<
912 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
914 parseType(in
,t
, unnamed_types
, named_types
);
917 getLAnglebracket(in
);
920 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
921 getRAnglebracket(in
); //</type>
924 /**************************************************************************
926 * getComa, getName, getNumber, getEqual
928 * Read a token from the input file, check its type, return it scontent.
931 * in , input file handle.
934 * address of token content.
936 **************************************************************************/
938 char *getName(parse_file_t
* in
)
942 token
= getToken(in
);
943 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
947 int getNumber(parse_file_t
* in
)
951 token
= getToken(in
);
952 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
956 char *getForwardslash(parse_file_t
* in
)
960 token
= getToken(in
);
961 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
962 /* Mathieu : final / is optional now. */
963 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
968 char *getLAnglebracket(parse_file_t
* in
)
972 token
= getToken(in
);
973 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
977 char *getRAnglebracket(parse_file_t
* in
)
981 token
= getToken(in
);
982 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
986 char *getQuotedString(parse_file_t
* in
)
990 token
= getToken(in
);
991 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
995 char * getEqual(parse_file_t
*in
)
999 token
= getToken(in
);
1000 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1004 char seekNextChar(parse_file_t
*in
)
1007 while((car
= getc(in
->fp
)) != EOF
) {
1016 /******************************************************************
1018 * getToken, ungetToken
1020 * Read a token from the input file and return its type and content.
1021 * Line numbers are accounted for and whitespace/comments are skipped.
1024 * in, input file handle.
1027 * address of token content.
1029 ******************************************************************/
1031 void ungetToken(parse_file_t
* in
)
1036 char *getToken(parse_file_t
* in
)
1040 int pos
= 0, escaped
;
1042 if(in
->unget
== 1) {
1047 /* skip whitespace and comments */
1049 while((car
= getc(fp
)) != EOF
) {
1052 if(car1
== '*') skipComment(in
);
1053 else if(car1
== '/') skipEOL(in
);
1055 car1
= ungetc(car1
,fp
);
1059 else if(car
== '\n') in
->lineno
++;
1060 else if(!isspace(car
)) break;
1068 in
->type
= FORWARDSLASH
;
1069 in
->buffer
[pos
] = car
;
1073 in
->type
= LANGLEBRACKET
;
1074 in
->buffer
[pos
] = car
;
1078 in
->type
= RANGLEBRACKET
;
1079 in
->buffer
[pos
] = car
;
1084 in
->buffer
[pos
] = car
;
1089 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1090 if(car
== '\\' && escaped
== 0) {
1091 in
->buffer
[pos
] = car
;
1096 if(car
== '"' && escaped
== 0) break;
1097 if(car
== '\n' && escaped
== 0) {
1098 in
->error(in
, "non escaped newline inside quoted string");
1100 if(car
== '\n') in
->lineno
++;
1101 in
->buffer
[pos
] = car
;
1105 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1106 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1107 in
->type
= QUOTEDSTRING
;
1111 in
->buffer
[pos
] = car
;
1113 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1118 in
->buffer
[pos
] = car
;
1121 if(car
== EOF
) ungetc(car
,fp
);
1122 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1125 else if(isalpha(car
)) {
1126 in
->buffer
[0] = car
;
1128 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1129 if(!(isalnum(car
) || car
== '_')) {
1133 in
->buffer
[pos
] = car
;
1136 if(car
== EOF
) ungetc(car
,fp
);
1137 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1140 else in
->error(in
, "invalid character, unrecognized token");
1142 in
->buffer
[pos
] = 0;
1146 void skipComment(parse_file_t
* in
)
1149 while((car
= getc(in
->fp
)) != EOF
) {
1150 if(car
== '\n') in
->lineno
++;
1151 else if(car
== '*') {
1153 if(car
==EOF
) break;
1154 if(car
== '/') return;
1158 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1161 void skipEOL(parse_file_t
* in
)
1164 while((car
= getc(in
->fp
)) != EOF
) {
1170 if(car
== EOF
)ungetc(car
, in
->fp
);
1173 /*****************************************************************************
1175 * checkNamedTypesImplemented : check if all named types have definition
1176 ****************************************************************************/
1178 void checkNamedTypesImplemented(table_t
* named_types
)
1180 type_descriptor_t
*t
;
1184 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1185 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1186 if(t
->type
== NONE
){
1187 sprintf(str
,"named type '%s' has no definition",
1188 (char*)named_types
->keys
.array
[pos
]);
1189 error_callback(NULL
,str
);
1195 /*****************************************************************************
1197 * generateChecksum : generate checksum for the facility
1199 * facName : name of facility
1201 * checksum : checksum for the facility
1202 ****************************************************************************/
1204 void generateChecksum(char* facName
,
1205 unsigned long * checksum
, sequence_t
* events
)
1211 crc
= crc32(facName
);
1212 for(pos
= 0; pos
< events
->position
; pos
++){
1213 ev
= (event_t
*)(events
->array
[pos
]);
1214 crc
= partial_crc32(ev
->name
, crc
);
1215 for(unsigned int i
= 0; i
< ev
->fields
.position
; i
++) {
1216 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1217 crc
= partial_crc32(f
->name
, crc
);
1218 crc
= getTypeChecksum(crc
, f
->type
);
1224 /*****************************************************************************
1226 * getTypeChecksum : generate checksum by type info
1228 * crc : checksum generated so far
1229 * type : type descriptor containing type info
1231 * unsigned long : checksum
1232 *****************************************************************************/
1234 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1236 unsigned long crc
= aCrc
;
1237 char * str
= NULL
, buf
[16];
1243 str
= intOutputTypes
[getSizeindex(type
->size
)];
1246 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1249 str
= allocAndCopy("void *");
1253 str
= allocAndCopy("signed char");
1257 str
= allocAndCopy("unsigned char");
1261 str
= allocAndCopy("short");
1265 str
= allocAndCopy("unsigned short");
1269 str
= allocAndCopy("int");
1273 str
= allocAndCopy("uint");
1277 str
= allocAndCopy("long");
1281 str
= allocAndCopy("unsigned long");
1285 str
= allocAndCopy("size_t");
1289 str
= allocAndCopy("ssize_t");
1293 str
= allocAndCopy("off_t");
1297 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1300 str
= allocAndCopy("string");
1304 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1305 str
= allocAndCopy("enum");
1309 sprintf(buf
,"%llu", type
->size
);
1310 str
= appendString("array ",buf
);
1314 sprintf(buf
,"%llu", type
->size
);
1315 str
= appendString("sequence ",buf
);
1319 str
= allocAndCopy("struct");
1323 str
= allocAndCopy("union");
1327 error_callback(NULL
, "named type has no definition");
1331 crc
= partial_crc32(str
,crc
);
1334 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1336 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1337 crc
= getTypeChecksum(crc
,type
->nested_type
);
1338 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1339 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1340 fld
= (field_t
*) type
->fields
.array
[pos
];
1341 crc
= partial_crc32(fld
->name
,crc
);
1342 crc
= getTypeChecksum(crc
, fld
->type
);
1344 }else if(type
->type
== ENUM
){
1345 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1346 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1353 /* Event type descriptors */
1354 void freeType(type_descriptor_t
* tp
)
1359 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1360 if(tp
->type
== ENUM
) {
1361 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1362 free(tp
->labels
.array
[pos2
]);
1364 sequence_dispose(&(tp
->labels
));
1366 if(tp
->type
== STRUCT
) {
1367 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1368 f
= (field_t
*) tp
->fields
.array
[pos2
];
1370 free(f
->description
);
1373 sequence_dispose(&(tp
->fields
));
1377 void freeNamedType(table_t
* t
)
1380 type_descriptor_t
* td
;
1382 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1383 free((char *)t
->keys
.array
[pos
]);
1384 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1390 void freeTypes(sequence_t
*t
)
1393 type_descriptor_t
*tp
;
1395 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1396 tp
= (type_descriptor_t
*)t
->array
[pos
];
1402 void freeEvents(sequence_t
*t
)
1407 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1408 ev
= (event_t
*) t
->array
[pos
];
1410 free(ev
->description
);
1411 sequence_dispose(&ev
->fields
);
1418 /* Extensible array */
1420 void sequence_init(sequence_t
*t
)
1424 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1427 void sequence_dispose(sequence_t
*t
)
1434 void sequence_push(sequence_t
*t
, void *elem
)
1438 if(t
->position
>= t
->size
) {
1440 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1441 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1442 t
->size
= t
->size
* 2;
1445 t
->array
[t
->position
] = elem
;
1449 void *sequence_pop(sequence_t
*t
)
1451 return t
->array
[t
->position
--];
1455 /* Hash table API, implementation is just linear search for now */
1457 void table_init(table_t
*t
)
1459 sequence_init(&(t
->keys
));
1460 sequence_init(&(t
->values
));
1463 void table_dispose(table_t
*t
)
1465 sequence_dispose(&(t
->keys
));
1466 sequence_dispose(&(t
->values
));
1469 void table_insert(table_t
*t
, char *key
, void *value
)
1471 sequence_push(&(t
->keys
),key
);
1472 sequence_push(&(t
->values
),value
);
1475 void *table_find(table_t
*t
, char *key
)
1478 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1479 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1480 return(t
->values
.array
[pos
]);
1485 void table_insert_int(table_t
*t
, int *key
, void *value
)
1487 sequence_push(&(t
->keys
),key
);
1488 sequence_push(&(t
->values
),value
);
1491 void *table_find_int(table_t
*t
, int *key
)
1494 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1495 if(*key
== *(int *)t
->keys
.array
[pos
])
1496 return(t
->values
.array
[pos
]);
1502 /* Concatenate strings */
1504 char *appendString(char *s
, char *suffix
)
1507 if(suffix
== NULL
) return s
;
1509 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.129801 seconds and 4 git commands to generate.