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
)
472 //<event name=eventtype_name>
473 getEventAttributes(in
, ev
);
474 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
475 getRAnglebracket(in
);
477 //<description>...</descriptio>
478 ev
->description
= getDescription(in
);
480 //event can have STRUCT, TYPEREF or NOTHING
481 getLAnglebracket(in
);
483 token
= getToken(in
);
484 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
486 }else if(in
->type
== NAME
){
487 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
489 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
490 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
491 in
->error(in
,"type must be a struct");
492 }else in
->error(in
, "not a valid type");
494 getLAnglebracket(in
);
496 }else in
->error(in
,"not a struct type");
499 if(strcmp("event",token
))in
->error(in
,"not an event definition");
500 getRAnglebracket(in
); //</event>
503 /*****************************************************************************
505 * parseField : get field infomation from buffer
507 * in : input file handle
508 * t : type descriptor
509 * unnamed_types : array of unamed types
510 * named_types : array of named types
511 ****************************************************************************/
513 void parseFields(parse_file_t
*in
, type_descriptor_t
*t
,
514 sequence_t
* unnamed_types
,
515 table_t
* named_types
)
520 f
= (field_t
*)memAlloc(sizeof(field_t
));
521 sequence_push(&(t
->fields
),f
);
523 //<field name=field_name> <description> <type> </field>
524 getFieldAttributes(in
, f
);
525 if(f
->name
== NULL
) in
->error(in
, "Field not named");
526 getRAnglebracket(in
);
528 f
->description
= getDescription(in
);
531 getLAnglebracket(in
);
532 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
534 getLAnglebracket(in
);
537 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
538 getRAnglebracket(in
); //</field>
542 /*****************************************************************************
544 * parseType : get type information, type can be :
546 * int(size,fmt); uint(size,fmt); float(size,fmt);
547 * string(fmt); enum(size,fmt,(label1,label2...))
549 * array(arraySize, type); sequence(lengthSize,type)
550 * struct(field(name,type,description)...)
554 * in : input file handle
555 * inType : a type descriptor
556 * unnamed_types : array of unamed types
557 * named_types : array of named types
559 * type_descriptor* : a type descriptor
560 ****************************************************************************/
562 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
563 sequence_t
* unnamed_types
, table_t
* named_types
)
566 type_descriptor_t
*t
;
569 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
573 sequence_push(unnamed_types
,t
);
579 if(strcmp(token
,"struct") == 0) {
581 getTypeAttributes(in
, t
);
582 getRAnglebracket(in
); //<struct>
583 getLAnglebracket(in
); //<field name=..>
584 token
= getToken(in
);
585 sequence_init(&(t
->fields
));
586 while(strcmp("field",token
) == 0){
587 parseFields(in
,t
, unnamed_types
, named_types
);
590 getLAnglebracket(in
);
591 token
= getToken(in
);
593 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
595 if(strcmp("struct",token
)!=0)
596 in
->error(in
,"not a valid structure definition");
597 getRAnglebracket(in
); //</struct>
599 else if(strcmp(token
,"union") == 0) {
601 getTypeAttributes(in
, t
);
602 getRAnglebracket(in
); //<union>
604 getLAnglebracket(in
); //<field name=..>
605 token
= getToken(in
);
606 sequence_init(&(t
->fields
));
607 while(strcmp("field",token
) == 0){
608 parseFields(in
,t
, unnamed_types
, named_types
);
611 getLAnglebracket(in
);
612 token
= getToken(in
);
614 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
616 if(strcmp("union",token
)!=0)
617 in
->error(in
,"not a valid union definition");
618 getRAnglebracket(in
); //</union>
620 else if(strcmp(token
,"array") == 0) {
622 getTypeAttributes(in
, t
);
623 if(t
->size
== 0) in
->error(in
, "Array has empty size");
625 getRAnglebracket(in
); //<array size=n>
627 getLAnglebracket(in
); //<type struct>
628 t
->nested_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
630 getLAnglebracket(in
); //</array>
633 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
634 getRAnglebracket(in
); //</array>
636 else if(strcmp(token
,"sequence") == 0) {
638 getTypeAttributes(in
, t
);
639 if(t
->size
== 0) in
->error(in
, "Sequence has empty lengthsize");
641 getRAnglebracket(in
); //<sequence lengthsize=isize>
643 getLAnglebracket(in
); //<type struct>
644 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
646 getLAnglebracket(in
); //</sequence>
649 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
650 getRAnglebracket(in
); //</sequence>
652 else if(strcmp(token
,"enum") == 0) {
655 sequence_init(&(t
->labels
));
656 sequence_init(&(t
->labels_description
));
657 t
->already_printed
= 0;
658 getTypeAttributes(in
, t
);
659 //if(t->size == 0) in->error(in, "Sequence has empty size");
660 //Mathieu : we fix enum size to 4 bytes. GCC is always like this.
661 //fox copy optimisation.
662 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of 4.");
664 getRAnglebracket(in
);
666 //<label name=label1 value=n/>
667 getLAnglebracket(in
);
668 token
= getToken(in
); //"label" or "/"
669 while(strcmp("label",token
) == 0){
670 str
= allocAndCopy(getNameAttribute(in
));
671 token
= getValueStrAttribute(in
);
673 str1
= appendString(str
,"=");
675 str
= appendString(str1
,token
);
677 sequence_push(&(t
->labels
),str
);
680 sequence_push(&(t
->labels
),str
);
683 getRAnglebracket(in
);
685 //read description if any. May be NULL.
686 str
= allocAndCopy(getDescription(in
));
687 sequence_push(&(t
->labels_description
),str
);
689 //next label definition
690 getLAnglebracket(in
);
691 token
= getToken(in
); //"label" or "/"
693 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
695 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
696 getRAnglebracket(in
); //</label>
698 else if(strcmp(token
,"int_fixed") == 0) {
700 getTypeAttributes(in
, t
);
701 if(t
->size
== 0) in
->error(in
, "int has empty size");
703 getRAnglebracket(in
);
705 else if(strcmp(token
,"uint_fixed") == 0) {
706 t
->type
= UINT_FIXED
;
707 getTypeAttributes(in
, t
);
708 if(t
->size
== 0) in
->error(in
, "uint has empty size");
710 getRAnglebracket(in
);
712 else if(strcmp(token
,"char") == 0) {
714 getTypeAttributes(in
, t
);
716 getRAnglebracket(in
);
718 else if(strcmp(token
,"uchar") == 0) {
720 getTypeAttributes(in
, t
);
722 getRAnglebracket(in
);
724 else if(strcmp(token
,"short") == 0) {
726 getTypeAttributes(in
, t
);
728 getRAnglebracket(in
);
730 else if(strcmp(token
,"ushort") == 0) {
732 getTypeAttributes(in
, t
);
734 getRAnglebracket(in
);
736 else if(strcmp(token
,"int") == 0) {
738 getTypeAttributes(in
, t
);
740 getRAnglebracket(in
);
742 else if(strcmp(token
,"uint") == 0) {
744 getTypeAttributes(in
, t
);
746 getRAnglebracket(in
);
749 else if(strcmp(token
,"pointer") == 0) {
751 getTypeAttributes(in
, t
);
753 getRAnglebracket(in
);
755 else if(strcmp(token
,"long") == 0) {
757 getTypeAttributes(in
, t
);
759 getRAnglebracket(in
);
761 else if(strcmp(token
,"ulong") == 0) {
763 getTypeAttributes(in
, t
);
765 getRAnglebracket(in
);
767 else if(strcmp(token
,"size_t") == 0) {
769 getTypeAttributes(in
, t
);
771 getRAnglebracket(in
);
773 else if(strcmp(token
,"ssize_t") == 0) {
775 getTypeAttributes(in
, t
);
777 getRAnglebracket(in
);
779 else if(strcmp(token
,"off_t") == 0) {
781 getTypeAttributes(in
, t
);
783 getRAnglebracket(in
);
785 else if(strcmp(token
,"float") == 0) {
787 getTypeAttributes(in
, t
);
789 getRAnglebracket(in
);
791 else if(strcmp(token
,"string") == 0) {
793 getTypeAttributes(in
, t
);
795 getRAnglebracket(in
);
797 else if(strcmp(token
,"typeref") == 0){
798 // Must be a named type
800 in
->error(in
,"Named type cannot refer to a named type");
803 sequence_pop(unnamed_types
);
804 token
= getNameAttribute(in
);
805 t
= find_named_type(token
, named_types
);
806 getForwardslash(in
); //<typeref name=type_name/>
807 getRAnglebracket(in
);
810 }else in
->error(in
,"not a valid type");
815 /*****************************************************************************
817 * find_named_type : find a named type from hash table
820 * named_types : array of named types
822 * type_descriptor * : a type descriptor
823 *****************************************************************************/
825 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
827 type_descriptor_t
*t
;
829 t
= table_find(named_types
,name
);
831 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
832 t
->type_name
= allocAndCopy(name
);
835 table_insert(named_types
,t
->type_name
,t
);
836 // table_insert(named_types,allocAndCopy(name),t);
841 /*****************************************************************************
843 * parseTypeDefinition : get type information from type definition
845 * in : input file handle
846 * unnamed_types : array of unamed types
847 * named_types : array of named types
848 *****************************************************************************/
850 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
851 table_t
* named_types
)
854 type_descriptor_t
*t
;
856 token
= getNameAttribute(in
);
857 if(token
== NULL
) in
->error(in
, "Type has empty name");
858 t
= find_named_type(token
, named_types
);
860 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
861 getRAnglebracket(in
); //<type name=type_name>
862 getLAnglebracket(in
); //<
864 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
866 parseType(in
,t
, unnamed_types
, named_types
);
869 getLAnglebracket(in
);
872 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
873 getRAnglebracket(in
); //</type>
876 /**************************************************************************
878 * getComa, getName, getNumber, getEqual
880 * Read a token from the input file, check its type, return it scontent.
883 * in , input file handle.
886 * address of token content.
888 **************************************************************************/
890 char *getName(parse_file_t
* in
)
894 token
= getToken(in
);
895 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
899 int getNumber(parse_file_t
* in
)
903 token
= getToken(in
);
904 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
908 char *getForwardslash(parse_file_t
* in
)
912 token
= getToken(in
);
913 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
914 /* Mathieu : final / is optional now. */
915 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
920 char *getLAnglebracket(parse_file_t
* in
)
924 token
= getToken(in
);
925 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
929 char *getRAnglebracket(parse_file_t
* in
)
933 token
= getToken(in
);
934 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
938 char *getQuotedString(parse_file_t
* in
)
942 token
= getToken(in
);
943 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
947 char * getEqual(parse_file_t
*in
)
951 token
= getToken(in
);
952 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
956 char seekNextChar(parse_file_t
*in
)
959 while((car
= getc(in
->fp
)) != EOF
) {
968 /******************************************************************
970 * getToken, ungetToken
972 * Read a token from the input file and return its type and content.
973 * Line numbers are accounted for and whitespace/comments are skipped.
976 * in, input file handle.
979 * address of token content.
981 ******************************************************************/
983 void ungetToken(parse_file_t
* in
)
988 char *getToken(parse_file_t
* in
)
992 int pos
= 0, escaped
;
999 /* skip whitespace and comments */
1001 while((car
= getc(fp
)) != EOF
) {
1004 if(car1
== '*') skipComment(in
);
1005 else if(car1
== '/') skipEOL(in
);
1007 car1
= ungetc(car1
,fp
);
1011 else if(car
== '\n') in
->lineno
++;
1012 else if(!isspace(car
)) break;
1020 in
->type
= FORWARDSLASH
;
1021 in
->buffer
[pos
] = car
;
1025 in
->type
= LANGLEBRACKET
;
1026 in
->buffer
[pos
] = car
;
1030 in
->type
= RANGLEBRACKET
;
1031 in
->buffer
[pos
] = car
;
1036 in
->buffer
[pos
] = car
;
1041 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1042 if(car
== '\\' && escaped
== 0) {
1043 in
->buffer
[pos
] = car
;
1048 if(car
== '"' && escaped
== 0) break;
1049 if(car
== '\n' && escaped
== 0) {
1050 in
->error(in
, "non escaped newline inside quoted string");
1052 if(car
== '\n') in
->lineno
++;
1053 in
->buffer
[pos
] = car
;
1057 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1058 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1059 in
->type
= QUOTEDSTRING
;
1063 in
->buffer
[pos
] = car
;
1065 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1070 in
->buffer
[pos
] = car
;
1073 if(car
== EOF
) ungetc(car
,fp
);
1074 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1077 else if(isalpha(car
)) {
1078 in
->buffer
[0] = car
;
1080 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1081 if(!(isalnum(car
) || car
== '_')) {
1085 in
->buffer
[pos
] = car
;
1088 if(car
== EOF
) ungetc(car
,fp
);
1089 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1092 else in
->error(in
, "invalid character, unrecognized token");
1094 in
->buffer
[pos
] = 0;
1098 void skipComment(parse_file_t
* in
)
1101 while((car
= getc(in
->fp
)) != EOF
) {
1102 if(car
== '\n') in
->lineno
++;
1103 else if(car
== '*') {
1105 if(car
==EOF
) break;
1106 if(car
== '/') return;
1110 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1113 void skipEOL(parse_file_t
* in
)
1116 while((car
= getc(in
->fp
)) != EOF
) {
1122 if(car
== EOF
)ungetc(car
, in
->fp
);
1125 /*****************************************************************************
1127 * checkNamedTypesImplemented : check if all named types have definition
1128 ****************************************************************************/
1130 void checkNamedTypesImplemented(table_t
* named_types
)
1132 type_descriptor_t
*t
;
1136 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1137 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1138 if(t
->type
== NONE
){
1139 sprintf(str
,"named type '%s' has no definition",
1140 (char*)named_types
->keys
.array
[pos
]);
1141 error_callback(NULL
,str
);
1147 /*****************************************************************************
1149 * generateChecksum : generate checksum for the facility
1151 * facName : name of facility
1153 * checksum : checksum for the facility
1154 ****************************************************************************/
1156 void generateChecksum(char* facName
,
1157 unsigned long * checksum
, sequence_t
* events
)
1164 crc
= crc32(facName
);
1165 for(pos
= 0; pos
< events
->position
; pos
++){
1166 ev
= (event_t
*)(events
->array
[pos
]);
1167 crc
= partial_crc32(ev
->name
,crc
);
1168 if(!ev
->type
) continue; //event without type
1169 if(ev
->type
->type
!= STRUCT
){
1170 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
1171 error_callback(NULL
, str
);
1173 crc
= getTypeChecksum(crc
, ev
->type
);
1178 /*****************************************************************************
1180 * getTypeChecksum : generate checksum by type info
1182 * crc : checksum generated so far
1183 * type : type descriptor containing type info
1185 * unsigned long : checksum
1186 *****************************************************************************/
1188 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1190 unsigned long crc
= aCrc
;
1191 char * str
= NULL
, buf
[16];
1197 str
= intOutputTypes
[getSizeindex(type
->size
)];
1200 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1203 str
= allocAndCopy("void *");
1207 str
= allocAndCopy("signed char");
1211 str
= allocAndCopy("unsigned char");
1215 str
= allocAndCopy("short");
1219 str
= allocAndCopy("unsigned short");
1223 str
= allocAndCopy("int");
1227 str
= allocAndCopy("uint");
1231 str
= allocAndCopy("long");
1235 str
= allocAndCopy("unsigned long");
1239 str
= allocAndCopy("size_t");
1243 str
= allocAndCopy("ssize_t");
1247 str
= allocAndCopy("off_t");
1251 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1254 str
= allocAndCopy("string");
1258 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1259 str
= allocAndCopy("enum");
1263 sprintf(buf
,"%llu", type
->size
);
1264 str
= appendString("array ",buf
);
1268 sprintf(buf
,"%llu", type
->size
);
1269 str
= appendString("sequence ",buf
);
1273 str
= allocAndCopy("struct");
1277 str
= allocAndCopy("union");
1281 error_callback(NULL
, "named type has no definition");
1285 crc
= partial_crc32(str
,crc
);
1288 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1290 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1291 crc
= getTypeChecksum(crc
,type
->nested_type
);
1292 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1293 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1294 fld
= (field_t
*) type
->fields
.array
[pos
];
1295 crc
= partial_crc32(fld
->name
,crc
);
1296 crc
= getTypeChecksum(crc
, fld
->type
);
1298 }else if(type
->type
== ENUM
){
1299 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1300 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1307 /* Event type descriptors */
1308 void freeType(type_descriptor_t
* tp
)
1313 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1314 if(tp
->type
== ENUM
) {
1315 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1316 free(tp
->labels
.array
[pos2
]);
1318 sequence_dispose(&(tp
->labels
));
1320 if(tp
->type
== STRUCT
) {
1321 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1322 f
= (field_t
*) tp
->fields
.array
[pos2
];
1324 free(f
->description
);
1327 sequence_dispose(&(tp
->fields
));
1331 void freeNamedType(table_t
* t
)
1334 type_descriptor_t
* td
;
1336 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1337 free((char *)t
->keys
.array
[pos
]);
1338 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1344 void freeTypes(sequence_t
*t
)
1347 type_descriptor_t
*tp
;
1349 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1350 tp
= (type_descriptor_t
*)t
->array
[pos
];
1356 void freeEvents(sequence_t
*t
)
1361 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1362 ev
= (event_t
*) t
->array
[pos
];
1364 free(ev
->description
);
1371 /* Extensible array */
1373 void sequence_init(sequence_t
*t
)
1377 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1380 void sequence_dispose(sequence_t
*t
)
1387 void sequence_push(sequence_t
*t
, void *elem
)
1391 if(t
->position
>= t
->size
) {
1393 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1394 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1395 t
->size
= t
->size
* 2;
1398 t
->array
[t
->position
] = elem
;
1402 void *sequence_pop(sequence_t
*t
)
1404 return t
->array
[t
->position
--];
1408 /* Hash table API, implementation is just linear search for now */
1410 void table_init(table_t
*t
)
1412 sequence_init(&(t
->keys
));
1413 sequence_init(&(t
->values
));
1416 void table_dispose(table_t
*t
)
1418 sequence_dispose(&(t
->keys
));
1419 sequence_dispose(&(t
->values
));
1422 void table_insert(table_t
*t
, char *key
, void *value
)
1424 sequence_push(&(t
->keys
),key
);
1425 sequence_push(&(t
->values
),value
);
1428 void *table_find(table_t
*t
, char *key
)
1431 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1432 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1433 return(t
->values
.array
[pos
]);
1438 void table_insert_int(table_t
*t
, int *key
, void *value
)
1440 sequence_push(&(t
->keys
),key
);
1441 sequence_push(&(t
->values
),value
);
1444 void *table_find_int(table_t
*t
, int *key
)
1447 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1448 if(*key
== *(int *)t
->keys
.array
[pos
])
1449 return(t
->values
.array
[pos
]);
1455 /* Concatenate strings */
1457 char *appendString(char *s
, char *suffix
)
1460 if(suffix
== NULL
) return s
;
1462 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.089559 seconds and 5 git commands to generate.