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
)
186 token
= getToken(in
);
187 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
192 if(!strcmp("format",token
)) {
194 t
->fmt
= allocAndCopy(getQuotedString(in
));
195 //} else if(!strcmp("name",token)) {
197 // car = seekNextChar(in);
198 // if(car == EOF) in->error(in,"name was expected");
199 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
200 // else t->type_name = allocAndCopy(getName(in));
201 } else if(!strcmp("size",token
) || !strcmp("lengthsize", token
)) {
203 t
->size
= getSize(in
);
204 } else if(!strcmp("align",token
)) {
206 t
->alignment
= getNumber(in
);
211 /**************************************************************************
215 * Read the attribute from the input file.
218 * in , input file handle.
219 * ev , the event to fill.
221 **************************************************************************/
223 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
230 ev
->per_tracefile
= 0;
233 token
= getToken(in
);
234 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
239 if(!strcmp("name",token
)) {
241 car
= seekNextChar(in
);
242 if(car
== EOF
) in
->error(in
,"name was expected");
243 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
244 else ev
->name
= allocAndCopy(getName(in
));
245 } else if(!strcmp("per_trace", token
)) {
247 } else if(!strcmp("per_tracefile", token
)) {
248 ev
->per_tracefile
= 1;
254 /**************************************************************************
256 * getFacilityAttributes
258 * Read the attribute from the input file.
261 * in , input file handle.
262 * fac , the facility to fill.
264 **************************************************************************/
266 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
274 token
= getToken(in
);
275 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
280 if(!strcmp("name",token
)) {
282 car
= seekNextChar(in
);
283 if(car
== EOF
) in
->error(in
,"name was expected");
284 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
285 else fac
->name
= allocAndCopy(getName(in
));
290 /**************************************************************************
294 * Read the attribute from the input file.
297 * in , input file handle.
298 * f , the field to fill.
300 **************************************************************************/
302 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
310 token
= getToken(in
);
311 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
316 if(!strcmp("name",token
)) {
318 car
= seekNextChar(in
);
319 if(car
== EOF
) in
->error(in
,"name was expected");
320 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
321 else f
->name
= allocAndCopy(getName(in
));
326 char *getNameAttribute(parse_file_t
*in
)
333 token
= getToken(in
);
334 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
339 if(!strcmp("name",token
)) {
341 car
= seekNextChar(in
);
342 if(car
== EOF
) in
->error(in
,"name was expected");
343 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
344 else name
= allocAndCopy(getName(in
));
347 if(name
== NULL
) in
->error(in
, "Name was expected");
354 //for <label name=label_name value=n format="..."/>, value is an option
355 char * getValueStrAttribute(parse_file_t
*in
)
359 token
= getToken(in
);
360 if(strcmp("/",token
) == 0){
365 if(strcmp("value",token
))in
->error(in
,"value was expected");
367 token
= getToken(in
);
368 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
372 char * getDescription(parse_file_t
*in
)
375 char * token
, car
, *str
;
379 getLAnglebracket(in
);
381 if(strcmp("description",token
)){
382 fseek(in
->fp
, pos
, SEEK_SET
);
386 getRAnglebracket(in
);
389 while((car
= getc(in
->fp
)) != EOF
) {
390 if(car
== '<') break;
391 if(car
== '\0') continue;
392 in
->buffer
[pos
] = car
;
395 if(car
== EOF
)in
->error(in
,"not a valid description");
396 in
->buffer
[pos
] = '\0';
398 str
= allocAndCopy(in
->buffer
);
402 if(strcmp("description", token
))in
->error(in
,"not a valid description");
403 getRAnglebracket(in
);
408 /*****************************************************************************
410 * parseFacility : generate event list
412 * in : input file handle
413 * fac : empty facility
415 * fac : facility filled with event list
416 ****************************************************************************/
418 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
423 getFacilityAttributes(in
, fac
);
424 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
426 fac
->capname
= allocAndCopy(fac
->name
);
427 strupper(fac
->capname
);
428 getRAnglebracket(in
);
430 fac
->description
= getDescription(in
);
433 getLAnglebracket(in
);
435 token
= getToken(in
);
436 if(in
->type
== ENDFILE
)
437 in
->error(in
,"the definition of the facility is not finished");
439 if(strcmp("event",token
) == 0){
440 ev
= (event_t
*) memAlloc(sizeof(event_t
));
441 sequence_push(&(fac
->events
),ev
);
442 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
443 }else if(strcmp("type",token
) == 0){
444 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
445 }else if(in
->type
== FORWARDSLASH
){
447 }else in
->error(in
,"event or type token expected\n");
451 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
452 getRAnglebracket(in
); //</facility>
455 /*****************************************************************************
457 * parseEvent : generate event from event definition
459 * in : input file handle
461 * unnamed_types : array of unamed types
462 * named_types : array of named types
464 * ev : new event (parameters are passed to it)
465 ****************************************************************************/
467 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
468 table_t
* named_types
)
473 sequence_init(&(ev
->fields
));
474 //<event name=eventtype_name>
475 getEventAttributes(in
, ev
);
476 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
477 getRAnglebracket(in
);
479 //<description>...</description>
480 ev
->description
= getDescription(in
);
483 /* Events can have multiple fields. each field form at least a function
484 * parameter of the logging function. */
486 getLAnglebracket(in
);
487 token
= getToken(in
);
490 case FORWARDSLASH
: /* </event> */
492 if(strcmp("event",token
))in
->error(in
,"not an event definition");
493 getRAnglebracket(in
); //</event>
496 case NAME
: /* a field */
497 if(strcmp("field",token
))in
->error(in
,"expecting a field");
498 f
= (field_t
*)memAlloc(sizeof(field_t
));
499 sequence_push(&(ev
->fields
),f
);
500 parseFields(in
, f
, unnamed_types
, named_types
);
503 in
->error(in
, "expecting </event> or <field >");
508 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
510 }else if(in
->type
== NAME
){
511 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
513 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
514 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
515 in
->error(in
,"type must be a struct");
516 }else in
->error(in
, "not a valid type");
518 getLAnglebracket(in
);
520 }else in
->error(in
,"not a struct type");
521 getLAnglebracket(in
);
524 if(strcmp("event",token
))in
->error(in
,"not an event definition");
525 getRAnglebracket(in
); //</event>
529 /*****************************************************************************
531 * parseField : get field infomation from buffer
533 * in : input file handle
535 * unnamed_types : array of unamed types
536 * named_types : array of named types
537 ****************************************************************************/
539 void parseFields(parse_file_t
*in
, field_t
*f
,
540 sequence_t
* unnamed_types
,
541 table_t
* named_types
)
545 //<field name=field_name> <description> <type> </field>
546 getFieldAttributes(in
, f
);
547 if(f
->name
== NULL
) in
->error(in
, "Field not named");
548 getRAnglebracket(in
);
550 f
->description
= getDescription(in
);
553 getLAnglebracket(in
);
554 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
556 getLAnglebracket(in
);
559 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
560 getRAnglebracket(in
); //</field>
564 /*****************************************************************************
566 * parseType : get type information, type can be :
568 * int(size,fmt); uint(size,fmt); float(size,fmt);
569 * string(fmt); enum(size,fmt,(label1,label2...))
571 * array(arraySize, type); sequence(lengthSize,type)
572 * struct(field(name,type,description)...)
576 * in : input file handle
577 * inType : a type descriptor
578 * unnamed_types : array of unamed types
579 * named_types : array of named types
581 * type_descriptor* : a type descriptor
582 ****************************************************************************/
584 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
585 sequence_t
* unnamed_types
, table_t
* named_types
)
588 type_descriptor_t
*t
;
592 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
596 sequence_push(unnamed_types
,t
);
602 if(strcmp(token
,"struct") == 0) {
604 getTypeAttributes(in
, t
);
605 getRAnglebracket(in
); //<struct>
606 getLAnglebracket(in
); //<field name=..>
607 token
= getToken(in
);
608 sequence_init(&(t
->fields
));
609 while(strcmp("field",token
) == 0){
610 f
= (field_t
*)memAlloc(sizeof(field_t
));
611 sequence_push(&(t
->fields
),f
);
613 parseFields(in
, f
, unnamed_types
, named_types
);
616 getLAnglebracket(in
);
617 token
= getToken(in
);
619 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
621 if(strcmp("struct",token
)!=0)
622 in
->error(in
,"not a valid structure definition");
623 getRAnglebracket(in
); //</struct>
625 else if(strcmp(token
,"union") == 0) {
627 getTypeAttributes(in
, t
);
628 getRAnglebracket(in
); //<union>
630 getLAnglebracket(in
); //<field name=..>
631 token
= getToken(in
);
632 sequence_init(&(t
->fields
));
633 while(strcmp("field",token
) == 0){
634 f
= (field_t
*)memAlloc(sizeof(field_t
));
635 sequence_push(&(t
->fields
),f
);
636 parseFields(in
, f
, unnamed_types
, named_types
);
639 getLAnglebracket(in
);
640 token
= getToken(in
);
642 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
644 if(strcmp("union",token
)!=0)
645 in
->error(in
,"not a valid union definition");
646 getRAnglebracket(in
); //</union>
648 else if(strcmp(token
,"array") == 0) {
650 getTypeAttributes(in
, t
);
651 if(t
->size
== 0) in
->error(in
, "Array has empty size");
653 getRAnglebracket(in
); //<array size=n>
655 getLAnglebracket(in
); //<type struct>
656 t
->nested_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
658 getLAnglebracket(in
); //</array>
661 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
662 getRAnglebracket(in
); //</array>
664 else if(strcmp(token
,"sequence") == 0) {
666 getTypeAttributes(in
, t
);
667 if(t
->size
== 0) in
->error(in
, "Sequence has empty lengthsize");
669 getRAnglebracket(in
); //<sequence lengthsize=isize>
671 getLAnglebracket(in
); //<type struct>
672 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
674 getLAnglebracket(in
); //</sequence>
677 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
678 getRAnglebracket(in
); //</sequence>
680 else if(strcmp(token
,"enum") == 0) {
683 sequence_init(&(t
->labels
));
684 sequence_init(&(t
->labels_description
));
685 t
->already_printed
= 0;
686 getTypeAttributes(in
, t
);
687 //if(t->size == 0) in->error(in, "Sequence has empty size");
688 //Mathieu : we fix enum size to 4 bytes. GCC is always like this.
689 //fox copy optimisation.
690 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of 4.");
692 getRAnglebracket(in
);
694 //<label name=label1 value=n/>
695 getLAnglebracket(in
);
696 token
= getToken(in
); //"label" or "/"
697 while(strcmp("label",token
) == 0){
698 str
= allocAndCopy(getNameAttribute(in
));
699 token
= getValueStrAttribute(in
);
701 str1
= appendString(str
,"=");
703 str
= appendString(str1
,token
);
705 sequence_push(&(t
->labels
),str
);
708 sequence_push(&(t
->labels
),str
);
711 getRAnglebracket(in
);
713 //read description if any. May be NULL.
714 str
= allocAndCopy(getDescription(in
));
715 sequence_push(&(t
->labels_description
),str
);
717 //next label definition
718 getLAnglebracket(in
);
719 token
= getToken(in
); //"label" or "/"
721 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
723 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
724 getRAnglebracket(in
); //</label>
726 else if(strcmp(token
,"int_fixed") == 0) {
728 getTypeAttributes(in
, t
);
729 if(t
->size
== 0) in
->error(in
, "int has empty size");
731 getRAnglebracket(in
);
733 else if(strcmp(token
,"uint_fixed") == 0) {
734 t
->type
= UINT_FIXED
;
735 getTypeAttributes(in
, t
);
736 if(t
->size
== 0) in
->error(in
, "uint has empty size");
738 getRAnglebracket(in
);
740 else if(strcmp(token
,"char") == 0) {
742 getTypeAttributes(in
, t
);
744 getRAnglebracket(in
);
746 else if(strcmp(token
,"uchar") == 0) {
748 getTypeAttributes(in
, t
);
750 getRAnglebracket(in
);
752 else if(strcmp(token
,"short") == 0) {
754 getTypeAttributes(in
, t
);
756 getRAnglebracket(in
);
758 else if(strcmp(token
,"ushort") == 0) {
760 getTypeAttributes(in
, t
);
762 getRAnglebracket(in
);
764 else if(strcmp(token
,"int") == 0) {
766 getTypeAttributes(in
, t
);
768 getRAnglebracket(in
);
770 else if(strcmp(token
,"uint") == 0) {
772 getTypeAttributes(in
, t
);
774 getRAnglebracket(in
);
777 else if(strcmp(token
,"pointer") == 0) {
779 getTypeAttributes(in
, t
);
781 getRAnglebracket(in
);
783 else if(strcmp(token
,"long") == 0) {
785 getTypeAttributes(in
, t
);
787 getRAnglebracket(in
);
789 else if(strcmp(token
,"ulong") == 0) {
791 getTypeAttributes(in
, t
);
793 getRAnglebracket(in
);
795 else if(strcmp(token
,"size_t") == 0) {
797 getTypeAttributes(in
, t
);
799 getRAnglebracket(in
);
801 else if(strcmp(token
,"ssize_t") == 0) {
803 getTypeAttributes(in
, t
);
805 getRAnglebracket(in
);
807 else if(strcmp(token
,"off_t") == 0) {
809 getTypeAttributes(in
, t
);
811 getRAnglebracket(in
);
813 else if(strcmp(token
,"float") == 0) {
815 getTypeAttributes(in
, t
);
817 getRAnglebracket(in
);
819 else if(strcmp(token
,"string") == 0) {
821 getTypeAttributes(in
, t
);
823 getRAnglebracket(in
);
825 else if(strcmp(token
,"typeref") == 0){
826 // Must be a named type
828 in
->error(in
,"Named type cannot refer to a named type");
831 sequence_pop(unnamed_types
);
832 token
= getNameAttribute(in
);
833 t
= find_named_type(token
, named_types
);
834 getForwardslash(in
); //<typeref name=type_name/>
835 getRAnglebracket(in
);
838 }else in
->error(in
,"not a valid type");
843 /*****************************************************************************
845 * find_named_type : find a named type from hash table
848 * named_types : array of named types
850 * type_descriptor * : a type descriptor
851 *****************************************************************************/
853 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
855 type_descriptor_t
*t
;
857 t
= table_find(named_types
,name
);
859 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
860 t
->type_name
= allocAndCopy(name
);
863 table_insert(named_types
,t
->type_name
,t
);
864 // table_insert(named_types,allocAndCopy(name),t);
869 /*****************************************************************************
871 * parseTypeDefinition : get type information from type definition
873 * in : input file handle
874 * unnamed_types : array of unamed types
875 * named_types : array of named types
876 *****************************************************************************/
878 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
879 table_t
* named_types
)
882 type_descriptor_t
*t
;
884 token
= getNameAttribute(in
);
885 if(token
== NULL
) in
->error(in
, "Type has empty name");
886 t
= find_named_type(token
, named_types
);
888 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
889 getRAnglebracket(in
); //<type name=type_name>
890 getLAnglebracket(in
); //<
892 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
894 parseType(in
,t
, unnamed_types
, named_types
);
897 getLAnglebracket(in
);
900 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
901 getRAnglebracket(in
); //</type>
904 /**************************************************************************
906 * getComa, getName, getNumber, getEqual
908 * Read a token from the input file, check its type, return it scontent.
911 * in , input file handle.
914 * address of token content.
916 **************************************************************************/
918 char *getName(parse_file_t
* in
)
922 token
= getToken(in
);
923 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
927 int getNumber(parse_file_t
* in
)
931 token
= getToken(in
);
932 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
936 char *getForwardslash(parse_file_t
* in
)
940 token
= getToken(in
);
941 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
942 /* Mathieu : final / is optional now. */
943 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
948 char *getLAnglebracket(parse_file_t
* in
)
952 token
= getToken(in
);
953 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
957 char *getRAnglebracket(parse_file_t
* in
)
961 token
= getToken(in
);
962 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
966 char *getQuotedString(parse_file_t
* in
)
970 token
= getToken(in
);
971 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
975 char * getEqual(parse_file_t
*in
)
979 token
= getToken(in
);
980 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
984 char seekNextChar(parse_file_t
*in
)
987 while((car
= getc(in
->fp
)) != EOF
) {
996 /******************************************************************
998 * getToken, ungetToken
1000 * Read a token from the input file and return its type and content.
1001 * Line numbers are accounted for and whitespace/comments are skipped.
1004 * in, input file handle.
1007 * address of token content.
1009 ******************************************************************/
1011 void ungetToken(parse_file_t
* in
)
1016 char *getToken(parse_file_t
* in
)
1020 int pos
= 0, escaped
;
1022 if(in
->unget
== 1) {
1027 /* skip whitespace and comments */
1029 while((car
= getc(fp
)) != EOF
) {
1032 if(car1
== '*') skipComment(in
);
1033 else if(car1
== '/') skipEOL(in
);
1035 car1
= ungetc(car1
,fp
);
1039 else if(car
== '\n') in
->lineno
++;
1040 else if(!isspace(car
)) break;
1048 in
->type
= FORWARDSLASH
;
1049 in
->buffer
[pos
] = car
;
1053 in
->type
= LANGLEBRACKET
;
1054 in
->buffer
[pos
] = car
;
1058 in
->type
= RANGLEBRACKET
;
1059 in
->buffer
[pos
] = car
;
1064 in
->buffer
[pos
] = car
;
1069 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1070 if(car
== '\\' && escaped
== 0) {
1071 in
->buffer
[pos
] = car
;
1076 if(car
== '"' && escaped
== 0) break;
1077 if(car
== '\n' && escaped
== 0) {
1078 in
->error(in
, "non escaped newline inside quoted string");
1080 if(car
== '\n') in
->lineno
++;
1081 in
->buffer
[pos
] = car
;
1085 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1086 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1087 in
->type
= QUOTEDSTRING
;
1091 in
->buffer
[pos
] = car
;
1093 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1098 in
->buffer
[pos
] = car
;
1101 if(car
== EOF
) ungetc(car
,fp
);
1102 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1105 else if(isalpha(car
)) {
1106 in
->buffer
[0] = car
;
1108 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1109 if(!(isalnum(car
) || car
== '_')) {
1113 in
->buffer
[pos
] = car
;
1116 if(car
== EOF
) ungetc(car
,fp
);
1117 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1120 else in
->error(in
, "invalid character, unrecognized token");
1122 in
->buffer
[pos
] = 0;
1126 void skipComment(parse_file_t
* in
)
1129 while((car
= getc(in
->fp
)) != EOF
) {
1130 if(car
== '\n') in
->lineno
++;
1131 else if(car
== '*') {
1133 if(car
==EOF
) break;
1134 if(car
== '/') return;
1138 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1141 void skipEOL(parse_file_t
* in
)
1144 while((car
= getc(in
->fp
)) != EOF
) {
1150 if(car
== EOF
)ungetc(car
, in
->fp
);
1153 /*****************************************************************************
1155 * checkNamedTypesImplemented : check if all named types have definition
1156 ****************************************************************************/
1158 void checkNamedTypesImplemented(table_t
* named_types
)
1160 type_descriptor_t
*t
;
1164 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1165 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1166 if(t
->type
== NONE
){
1167 sprintf(str
,"named type '%s' has no definition",
1168 (char*)named_types
->keys
.array
[pos
]);
1169 error_callback(NULL
,str
);
1175 /*****************************************************************************
1177 * generateChecksum : generate checksum for the facility
1179 * facName : name of facility
1181 * checksum : checksum for the facility
1182 ****************************************************************************/
1184 void generateChecksum(char* facName
,
1185 unsigned long * checksum
, sequence_t
* events
)
1191 crc
= crc32(facName
);
1192 for(pos
= 0; pos
< events
->position
; pos
++){
1193 ev
= (event_t
*)(events
->array
[pos
]);
1194 crc
= partial_crc32(ev
->name
, crc
);
1195 for(unsigned int i
= 0; i
< ev
->fields
.position
; i
++) {
1196 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1197 crc
= partial_crc32(f
->name
, crc
);
1198 crc
= getTypeChecksum(crc
, f
->type
);
1204 /*****************************************************************************
1206 * getTypeChecksum : generate checksum by type info
1208 * crc : checksum generated so far
1209 * type : type descriptor containing type info
1211 * unsigned long : checksum
1212 *****************************************************************************/
1214 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1216 unsigned long crc
= aCrc
;
1217 char * str
= NULL
, buf
[16];
1223 str
= intOutputTypes
[getSizeindex(type
->size
)];
1226 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1229 str
= allocAndCopy("void *");
1233 str
= allocAndCopy("signed char");
1237 str
= allocAndCopy("unsigned char");
1241 str
= allocAndCopy("short");
1245 str
= allocAndCopy("unsigned short");
1249 str
= allocAndCopy("int");
1253 str
= allocAndCopy("uint");
1257 str
= allocAndCopy("long");
1261 str
= allocAndCopy("unsigned long");
1265 str
= allocAndCopy("size_t");
1269 str
= allocAndCopy("ssize_t");
1273 str
= allocAndCopy("off_t");
1277 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1280 str
= allocAndCopy("string");
1284 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1285 str
= allocAndCopy("enum");
1289 sprintf(buf
,"%llu", type
->size
);
1290 str
= appendString("array ",buf
);
1294 sprintf(buf
,"%llu", type
->size
);
1295 str
= appendString("sequence ",buf
);
1299 str
= allocAndCopy("struct");
1303 str
= allocAndCopy("union");
1307 error_callback(NULL
, "named type has no definition");
1311 crc
= partial_crc32(str
,crc
);
1314 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1316 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1317 crc
= getTypeChecksum(crc
,type
->nested_type
);
1318 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1319 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1320 fld
= (field_t
*) type
->fields
.array
[pos
];
1321 crc
= partial_crc32(fld
->name
,crc
);
1322 crc
= getTypeChecksum(crc
, fld
->type
);
1324 }else if(type
->type
== ENUM
){
1325 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1326 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1333 /* Event type descriptors */
1334 void freeType(type_descriptor_t
* tp
)
1339 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1340 if(tp
->type
== ENUM
) {
1341 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1342 free(tp
->labels
.array
[pos2
]);
1344 sequence_dispose(&(tp
->labels
));
1346 if(tp
->type
== STRUCT
) {
1347 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1348 f
= (field_t
*) tp
->fields
.array
[pos2
];
1350 free(f
->description
);
1353 sequence_dispose(&(tp
->fields
));
1357 void freeNamedType(table_t
* t
)
1360 type_descriptor_t
* td
;
1362 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1363 free((char *)t
->keys
.array
[pos
]);
1364 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1370 void freeTypes(sequence_t
*t
)
1373 type_descriptor_t
*tp
;
1375 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1376 tp
= (type_descriptor_t
*)t
->array
[pos
];
1382 void freeEvents(sequence_t
*t
)
1387 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1388 ev
= (event_t
*) t
->array
[pos
];
1390 free(ev
->description
);
1391 sequence_dispose(&ev
->fields
);
1398 /* Extensible array */
1400 void sequence_init(sequence_t
*t
)
1404 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1407 void sequence_dispose(sequence_t
*t
)
1414 void sequence_push(sequence_t
*t
, void *elem
)
1418 if(t
->position
>= t
->size
) {
1420 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1421 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1422 t
->size
= t
->size
* 2;
1425 t
->array
[t
->position
] = elem
;
1429 void *sequence_pop(sequence_t
*t
)
1431 return t
->array
[t
->position
--];
1435 /* Hash table API, implementation is just linear search for now */
1437 void table_init(table_t
*t
)
1439 sequence_init(&(t
->keys
));
1440 sequence_init(&(t
->values
));
1443 void table_dispose(table_t
*t
)
1445 sequence_dispose(&(t
->keys
));
1446 sequence_dispose(&(t
->values
));
1449 void table_insert(table_t
*t
, char *key
, void *value
)
1451 sequence_push(&(t
->keys
),key
);
1452 sequence_push(&(t
->values
),value
);
1455 void *table_find(table_t
*t
, char *key
)
1458 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1459 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1460 return(t
->values
.array
[pos
]);
1465 void table_insert_int(table_t
*t
, int *key
, void *value
)
1467 sequence_push(&(t
->keys
),key
);
1468 sequence_push(&(t
->values
),value
);
1471 void *table_find_int(table_t
*t
, int *key
)
1474 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1475 if(*key
== *(int *)t
->keys
.array
[pos
])
1476 return(t
->values
.array
[pos
]);
1482 /* Concatenate strings */
1484 char *appendString(char *s
, char *suffix
)
1487 if(suffix
== NULL
) return s
;
1489 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.08792 seconds and 4 git commands to generate.