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 static char *intOutputTypes
[] = {
47 "int8_t", "int16_t", "int32_t", "int64_t", "short int", "int", "long int" };
49 static char *uintOutputTypes
[] = {
50 "uint8_t", "uint16_t", "uint32_t", "uint64_t", "unsigned short int",
51 "unsigned int", "unsigned long int" };
53 static char *floatOutputTypes
[] = {
54 "undef", "undef", "float", "double", "undef", "float", "double" };
60 void strupper(char *string
)
71 int getSizeindex(int value
)
83 printf("Error : unknown value size %d\n", value
);
88 /*****************************************************************************
90 * getSize : translate from string to integer
92 * in : input file handle
95 *****************************************************************************/
97 int getSize(parse_file_t
*in
)
101 token
= getToken(in
);
102 if(in
->type
== NUMBER
) {
103 if(strcmp(token
,"1") == 0) return 0;
104 else if(strcmp(token
,"2") == 0) return 1;
105 else if(strcmp(token
,"4") == 0) return 2;
106 else if(strcmp(token
,"8") == 0) return 3;
108 else if(in
->type
== NAME
) {
109 if(strcmp(token
,"short") == 0) return 4;
110 else if(strcmp(token
,"medium") == 0) return 5;
111 else if(strcmp(token
,"long") == 0) return 6;
113 in
->error(in
,"incorrect size specification");
117 /*****************************************************************************
119 * error_callback : print out error info
121 * in : input file handle
122 * msg : message to be printed
123 ****************************************************************************/
125 void error_callback(parse_file_t
*in
, char *msg
)
128 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
135 /*****************************************************************************
137 * memAlloc : allocate memory
139 * size : required memory size
141 * void * : pointer to allocate memory or NULL
142 ****************************************************************************/
144 void * memAlloc(int size
)
147 if(size
== 0) return NULL
;
150 printf("Failed to allocate memory");
156 /*****************************************************************************
158 * allocAndCopy : allocate memory and initialize it
160 * str : string to be put in memory
162 * char * : pointer to allocate memory or NULL
163 ****************************************************************************/
165 char *allocAndCopy(char *str
)
168 if(str
== NULL
) return NULL
;
169 addr
= (char *)memAlloc(strlen(str
)+1);
174 /**************************************************************************
178 * Read the attribute from the input file.
181 * in , input file handle.
182 * t , the type descriptor to fill.
184 **************************************************************************/
186 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
)
195 token
= getToken(in
);
196 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
201 if(!strcmp("format",token
)) {
203 t
->fmt
= allocAndCopy(getQuotedString(in
));
204 //} else if(!strcmp("name",token)) {
206 // car = seekNextChar(in);
207 // if(car == EOF) in->error(in,"name was expected");
208 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
209 // else t->type_name = allocAndCopy(getName(in));
210 } else if(!strcmp("size",token
)) {
212 t
->size
= getSize(in
);
213 } else if(!strcmp("align",token
)) {
215 t
->alignment
= getNumber(in
);
220 /**************************************************************************
224 * Read the attribute from the input file.
227 * in , input file handle.
228 * ev , the event to fill.
230 **************************************************************************/
232 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
239 ev
->per_tracefile
= 0;
242 token
= getToken(in
);
243 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
248 if(!strcmp("name",token
)) {
250 car
= seekNextChar(in
);
251 if(car
== EOF
) in
->error(in
,"name was expected");
252 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
253 else ev
->name
= allocAndCopy(getName(in
));
254 } else if(!strcmp("per_trace", token
)) {
256 } else if(!strcmp("per_tracefile", token
)) {
257 ev
->per_tracefile
= 1;
263 /**************************************************************************
265 * getFacilityAttributes
267 * Read the attribute from the input file.
270 * in , input file handle.
271 * fac , the facility to fill.
273 **************************************************************************/
275 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
283 token
= getToken(in
);
284 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
289 if(!strcmp("name",token
)) {
291 car
= seekNextChar(in
);
292 if(car
== EOF
) in
->error(in
,"name was expected");
293 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
294 else fac
->name
= allocAndCopy(getName(in
));
299 /**************************************************************************
303 * Read the attribute from the input file.
306 * in , input file handle.
307 * f , the field to fill.
309 **************************************************************************/
311 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
319 token
= getToken(in
);
320 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
325 if(!strcmp("name",token
)) {
327 car
= seekNextChar(in
);
328 if(car
== EOF
) in
->error(in
,"name was expected");
329 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
330 else f
->name
= allocAndCopy(getName(in
));
335 char *getNameAttribute(parse_file_t
*in
)
342 token
= getToken(in
);
343 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
348 if(!strcmp("name",token
)) {
350 car
= seekNextChar(in
);
351 if(car
== EOF
) in
->error(in
,"name was expected");
352 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
353 else name
= allocAndCopy(getName(in
));
356 if(name
== NULL
) in
->error(in
, "Name was expected");
363 //for <label name=label_name value=n format="..."/>, value is an option
364 char * getValueStrAttribute(parse_file_t
*in
)
368 token
= getToken(in
);
369 if(strcmp("/",token
) == 0){
374 if(strcmp("value",token
))in
->error(in
,"value was expected");
376 token
= getToken(in
);
377 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
381 char * getDescription(parse_file_t
*in
)
384 char * token
, car
, *str
;
388 getLAnglebracket(in
);
390 if(strcmp("description",token
)){
391 fseek(in
->fp
, pos
, SEEK_SET
);
395 getRAnglebracket(in
);
398 while((car
= getc(in
->fp
)) != EOF
) {
399 if(car
== '<') break;
400 if(car
== '\0') continue;
401 in
->buffer
[pos
] = car
;
404 if(car
== EOF
)in
->error(in
,"not a valid description");
405 in
->buffer
[pos
] = '\0';
407 str
= allocAndCopy(in
->buffer
);
411 if(strcmp("description", token
))in
->error(in
,"not a valid description");
412 getRAnglebracket(in
);
417 /*****************************************************************************
419 * parseFacility : generate event list
421 * in : input file handle
422 * fac : empty facility
424 * fac : facility filled with event list
425 ****************************************************************************/
427 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
432 getFacilityAttributes(in
, fac
);
433 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
435 fac
->capname
= allocAndCopy(fac
->name
);
436 strupper(fac
->capname
);
437 getRAnglebracket(in
);
439 fac
->description
= getDescription(in
);
442 getLAnglebracket(in
);
444 token
= getToken(in
);
445 if(in
->type
== ENDFILE
)
446 in
->error(in
,"the definition of the facility is not finished");
448 if(strcmp("event",token
) == 0){
449 ev
= (event_t
*) memAlloc(sizeof(event_t
));
450 sequence_push(&(fac
->events
),ev
);
451 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
452 }else if(strcmp("type",token
) == 0){
453 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
454 }else if(in
->type
== FORWARDSLASH
){
456 }else in
->error(in
,"event or type token expected\n");
460 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
461 getRAnglebracket(in
); //</facility>
464 /*****************************************************************************
466 * parseEvent : generate event from event definition
468 * in : input file handle
470 * unnamed_types : array of unamed types
471 * named_types : array of named types
473 * ev : new event (parameters are passed to it)
474 ****************************************************************************/
476 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
477 table_t
* named_types
)
481 //<event name=eventtype_name>
482 getEventAttributes(in
, ev
);
483 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
484 getRAnglebracket(in
);
486 //<description>...</descriptio>
487 ev
->description
= getDescription(in
);
489 //event can have STRUCT, TYPEREF or NOTHING
490 getLAnglebracket(in
);
492 token
= getToken(in
);
493 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
495 }else if(in
->type
== NAME
){
496 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
498 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
499 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
500 in
->error(in
,"type must be a struct");
501 }else in
->error(in
, "not a valid type");
503 getLAnglebracket(in
);
505 }else in
->error(in
,"not a struct type");
508 if(strcmp("event",token
))in
->error(in
,"not an event definition");
509 getRAnglebracket(in
); //</event>
512 /*****************************************************************************
514 * parseField : get field infomation from buffer
516 * in : input file handle
517 * t : type descriptor
518 * unnamed_types : array of unamed types
519 * named_types : array of named types
520 ****************************************************************************/
522 void parseFields(parse_file_t
*in
, type_descriptor_t
*t
,
523 sequence_t
* unnamed_types
,
524 table_t
* named_types
)
529 f
= (field_t
*)memAlloc(sizeof(field_t
));
530 sequence_push(&(t
->fields
),f
);
532 //<field name=field_name> <description> <type> </field>
533 getFieldAttributes(in
, f
);
534 if(f
->name
== NULL
) in
->error(in
, "Field not named");
535 getRAnglebracket(in
);
537 f
->description
= getDescription(in
);
540 getLAnglebracket(in
);
541 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
543 getLAnglebracket(in
);
546 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
547 getRAnglebracket(in
); //</field>
551 /*****************************************************************************
553 * parseType : get type information, type can be :
555 * int(size,fmt); uint(size,fmt); float(size,fmt);
556 * string(fmt); enum(size,fmt,(label1,label2...))
558 * array(arraySize, type); sequence(lengthSize,type)
559 * struct(field(name,type,description)...)
563 * in : input file handle
564 * inType : a type descriptor
565 * unnamed_types : array of unamed types
566 * named_types : array of named types
568 * type_descriptor* : a type descriptor
569 ****************************************************************************/
571 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
572 sequence_t
* unnamed_types
, table_t
* named_types
)
575 type_descriptor_t
*t
;
578 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
582 sequence_push(unnamed_types
,t
);
588 if(strcmp(token
,"struct") == 0) {
590 getTypeAttributes(in
, t
);
591 getRAnglebracket(in
); //<struct>
592 getLAnglebracket(in
); //<field name=..>
593 token
= getToken(in
);
594 sequence_init(&(t
->fields
));
595 while(strcmp("field",token
) == 0){
596 parseFields(in
,t
, unnamed_types
, named_types
);
599 getLAnglebracket(in
);
600 token
= getToken(in
);
602 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
604 if(strcmp("struct",token
)!=0)
605 in
->error(in
,"not a valid structure definition");
606 getRAnglebracket(in
); //</struct>
608 else if(strcmp(token
,"union") == 0) {
610 getTypeAttributes(in
, t
);
611 if(t
->size
== -1) in
->error(in
, "Union has empty size");
612 getRAnglebracket(in
); //<union typecodesize=isize>
614 getLAnglebracket(in
); //<field name=..>
615 token
= getToken(in
);
616 sequence_init(&(t
->fields
));
617 while(strcmp("field",token
) == 0){
618 parseFields(in
,t
, unnamed_types
, named_types
);
621 getLAnglebracket(in
);
622 token
= getToken(in
);
624 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
626 if(strcmp("union",token
)!=0)
627 in
->error(in
,"not a valid union definition");
628 getRAnglebracket(in
); //</union>
630 else if(strcmp(token
,"array") == 0) {
632 getTypeAttributes(in
, t
);
633 if(t
->size
== -1) in
->error(in
, "Array has empty size");
634 getRAnglebracket(in
); //<array size=n>
636 getLAnglebracket(in
); //<type struct>
637 t
->nested_type
= parseType(in
, NULL
, unnamed_types
, named_types
);
639 getLAnglebracket(in
); //</array>
642 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
643 getRAnglebracket(in
); //</array>
645 else if(strcmp(token
,"sequence") == 0) {
647 getTypeAttributes(in
, t
);
648 if(t
->size
== -1) in
->error(in
, "Sequence has empty size");
649 getRAnglebracket(in
); //<array lengthsize=isize>
651 getLAnglebracket(in
); //<type struct>
652 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
654 getLAnglebracket(in
); //</sequence>
657 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
658 getRAnglebracket(in
); //</sequence>
660 else if(strcmp(token
,"enum") == 0) {
663 sequence_init(&(t
->labels
));
664 sequence_init(&(t
->labels_description
));
665 t
->already_printed
= 0;
666 getTypeAttributes(in
, t
);
667 if(t
->size
== -1) in
->error(in
, "Sequence has empty size");
668 getRAnglebracket(in
);
670 //<label name=label1 value=n/>
671 getLAnglebracket(in
);
672 token
= getToken(in
); //"label" or "/"
673 while(strcmp("label",token
) == 0){
674 str
= allocAndCopy(getNameAttribute(in
));
675 token
= getValueStrAttribute(in
);
677 str1
= appendString(str
,"=");
679 str
= appendString(str1
,token
);
681 sequence_push(&(t
->labels
),str
);
684 sequence_push(&(t
->labels
),str
);
687 getRAnglebracket(in
);
689 //read description if any. May be NULL.
690 str
= allocAndCopy(getDescription(in
));
691 sequence_push(&(t
->labels_description
),str
);
693 //next label definition
694 getLAnglebracket(in
);
695 token
= getToken(in
); //"label" or "/"
697 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
699 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
700 getRAnglebracket(in
); //</label>
702 else if(strcmp(token
,"int") == 0) {
704 getTypeAttributes(in
, t
);
705 if(t
->size
== -1) in
->error(in
, "int has empty size");
707 getRAnglebracket(in
);
709 else if(strcmp(token
,"uint") == 0) {
711 getTypeAttributes(in
, t
);
712 if(t
->size
== -1) in
->error(in
, "uint has empty size");
714 getRAnglebracket(in
);
716 else if(strcmp(token
,"pointer") == 0) {
718 getTypeAttributes(in
, t
);
720 getRAnglebracket(in
);
722 else if(strcmp(token
,"long") == 0) {
724 getTypeAttributes(in
, t
);
726 getRAnglebracket(in
);
728 else if(strcmp(token
,"ulong") == 0) {
730 getTypeAttributes(in
, t
);
732 getRAnglebracket(in
);
734 else if(strcmp(token
,"size_t") == 0) {
736 getTypeAttributes(in
, t
);
738 getRAnglebracket(in
);
740 else if(strcmp(token
,"ssize_t") == 0) {
742 getTypeAttributes(in
, t
);
744 getRAnglebracket(in
);
746 else if(strcmp(token
,"off_t") == 0) {
748 getTypeAttributes(in
, t
);
750 getRAnglebracket(in
);
752 else if(strcmp(token
,"float") == 0) {
754 getTypeAttributes(in
, t
);
756 getRAnglebracket(in
);
758 else if(strcmp(token
,"string") == 0) {
760 getTypeAttributes(in
, t
);
762 getRAnglebracket(in
);
764 else if(strcmp(token
,"typeref") == 0){
765 // Must be a named type
767 in
->error(in
,"Named type cannot refer to a named type");
770 sequence_pop(unnamed_types
);
771 token
= getNameAttribute(in
);
772 t
= find_named_type(token
, named_types
);
773 getForwardslash(in
); //<typeref name=type_name/>
774 getRAnglebracket(in
);
777 }else in
->error(in
,"not a valid type");
782 /*****************************************************************************
784 * find_named_type : find a named type from hash table
787 * named_types : array of named types
789 * type_descriptor * : a type descriptor
790 *****************************************************************************/
792 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
794 type_descriptor_t
*t
;
796 t
= table_find(named_types
,name
);
798 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
799 t
->type_name
= allocAndCopy(name
);
802 table_insert(named_types
,t
->type_name
,t
);
803 // table_insert(named_types,allocAndCopy(name),t);
808 /*****************************************************************************
810 * parseTypeDefinition : get type information from type definition
812 * in : input file handle
813 * unnamed_types : array of unamed types
814 * named_types : array of named types
815 *****************************************************************************/
817 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
818 table_t
* named_types
)
821 type_descriptor_t
*t
;
823 token
= getNameAttribute(in
);
824 if(token
== NULL
) in
->error(in
, "Type has empty name");
825 t
= find_named_type(token
, named_types
);
827 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
828 getRAnglebracket(in
); //<type name=type_name>
829 getLAnglebracket(in
); //<
831 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
833 parseType(in
,t
, unnamed_types
, named_types
);
836 getLAnglebracket(in
);
839 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
840 getRAnglebracket(in
); //</type>
843 /**************************************************************************
845 * getComa, getName, getNumber, getEqual
847 * Read a token from the input file, check its type, return it scontent.
850 * in , input file handle.
853 * address of token content.
855 **************************************************************************/
857 char *getName(parse_file_t
* in
)
861 token
= getToken(in
);
862 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
866 int getNumber(parse_file_t
* in
)
870 token
= getToken(in
);
871 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
875 char *getForwardslash(parse_file_t
* in
)
879 token
= getToken(in
);
880 if(in
->type
!= FORWARDSLASH
) in
->error(in
, "forward slash token was expected");
884 char *getLAnglebracket(parse_file_t
* in
)
888 token
= getToken(in
);
889 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
893 char *getRAnglebracket(parse_file_t
* in
)
897 token
= getToken(in
);
898 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
902 char *getQuotedString(parse_file_t
* in
)
906 token
= getToken(in
);
907 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
911 char * getEqual(parse_file_t
*in
)
915 token
= getToken(in
);
916 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
920 char seekNextChar(parse_file_t
*in
)
923 while((car
= getc(in
->fp
)) != EOF
) {
932 /******************************************************************
934 * getToken, ungetToken
936 * Read a token from the input file and return its type and content.
937 * Line numbers are accounted for and whitespace/comments are skipped.
940 * in, input file handle.
943 * address of token content.
945 ******************************************************************/
947 void ungetToken(parse_file_t
* in
)
952 char *getToken(parse_file_t
* in
)
956 int pos
= 0, escaped
;
963 /* skip whitespace and comments */
965 while((car
= getc(fp
)) != EOF
) {
968 if(car1
== '*') skipComment(in
);
969 else if(car1
== '/') skipEOL(in
);
971 car1
= ungetc(car1
,fp
);
975 else if(car
== '\n') in
->lineno
++;
976 else if(!isspace(car
)) break;
984 in
->type
= FORWARDSLASH
;
985 in
->buffer
[pos
] = car
;
989 in
->type
= LANGLEBRACKET
;
990 in
->buffer
[pos
] = car
;
994 in
->type
= RANGLEBRACKET
;
995 in
->buffer
[pos
] = car
;
1000 in
->buffer
[pos
] = car
;
1005 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1006 if(car
== '\\' && escaped
== 0) {
1007 in
->buffer
[pos
] = car
;
1012 if(car
== '"' && escaped
== 0) break;
1013 if(car
== '\n' && escaped
== 0) {
1014 in
->error(in
, "non escaped newline inside quoted string");
1016 if(car
== '\n') in
->lineno
++;
1017 in
->buffer
[pos
] = car
;
1021 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1022 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1023 in
->type
= QUOTEDSTRING
;
1027 in
->buffer
[pos
] = car
;
1029 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1034 in
->buffer
[pos
] = car
;
1037 if(car
== EOF
) ungetc(car
,fp
);
1038 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1041 else if(isalpha(car
)) {
1042 in
->buffer
[0] = car
;
1044 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1045 if(!(isalnum(car
) || car
== '_')) {
1049 in
->buffer
[pos
] = car
;
1052 if(car
== EOF
) ungetc(car
,fp
);
1053 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1056 else in
->error(in
, "invalid character, unrecognized token");
1058 in
->buffer
[pos
] = 0;
1062 void skipComment(parse_file_t
* in
)
1065 while((car
= getc(in
->fp
)) != EOF
) {
1066 if(car
== '\n') in
->lineno
++;
1067 else if(car
== '*') {
1069 if(car
==EOF
) break;
1070 if(car
== '/') return;
1074 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1077 void skipEOL(parse_file_t
* in
)
1080 while((car
= getc(in
->fp
)) != EOF
) {
1086 if(car
== EOF
)ungetc(car
, in
->fp
);
1089 /*****************************************************************************
1091 * checkNamedTypesImplemented : check if all named types have definition
1092 ****************************************************************************/
1094 void checkNamedTypesImplemented(table_t
* named_types
)
1096 type_descriptor_t
*t
;
1100 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1101 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1102 if(t
->type
== NONE
){
1103 sprintf(str
,"named type '%s' has no definition",
1104 (char*)named_types
->keys
.array
[pos
]);
1105 error_callback(NULL
,str
);
1111 /*****************************************************************************
1113 * generateChecksum : generate checksum for the facility
1115 * facName : name of facility
1117 * checksum : checksum for the facility
1118 ****************************************************************************/
1120 void generateChecksum(char* facName
,
1121 unsigned long * checksum
, sequence_t
* events
)
1128 crc
= crc32(facName
);
1129 for(pos
= 0; pos
< events
->position
; pos
++){
1130 ev
= (event_t
*)(events
->array
[pos
]);
1131 crc
= partial_crc32(ev
->name
,crc
);
1132 if(!ev
->type
) continue; //event without type
1133 if(ev
->type
->type
!= STRUCT
){
1134 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
1135 error_callback(NULL
, str
);
1137 crc
= getTypeChecksum(crc
, ev
->type
);
1142 /*****************************************************************************
1144 * getTypeChecksum : generate checksum by type info
1146 * crc : checksum generated so far
1147 * type : type descriptor containing type info
1149 * unsigned long : checksum
1150 *****************************************************************************/
1152 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1154 unsigned long crc
= aCrc
;
1155 char * str
= NULL
, buf
[16];
1161 str
= intOutputTypes
[type
->size
];
1164 str
= uintOutputTypes
[type
->size
];
1167 str
= allocAndCopy("void *");
1171 str
= allocAndCopy("long");
1175 str
= allocAndCopy("unsigned long");
1179 str
= allocAndCopy("size_t");
1183 str
= allocAndCopy("ssize_t");
1187 str
= allocAndCopy("off_t");
1191 str
= floatOutputTypes
[type
->size
];
1194 str
= allocAndCopy("string");
1198 str
= appendString("enum ", uintOutputTypes
[type
->size
]);
1202 sprintf(buf
,"%d",type
->size
);
1203 str
= appendString("array ",buf
);
1207 sprintf(buf
,"%d",type
->size
);
1208 str
= appendString("sequence ",buf
);
1212 str
= allocAndCopy("struct");
1216 str
= allocAndCopy("union");
1220 error_callback(NULL
, "named type has no definition");
1224 crc
= partial_crc32(str
,crc
);
1227 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1229 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1230 crc
= getTypeChecksum(crc
,type
->nested_type
);
1231 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1232 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1233 fld
= (field_t
*) type
->fields
.array
[pos
];
1234 crc
= partial_crc32(fld
->name
,crc
);
1235 crc
= getTypeChecksum(crc
, fld
->type
);
1237 }else if(type
->type
== ENUM
){
1238 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1239 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1246 /* Event type descriptors */
1247 void freeType(type_descriptor_t
* tp
)
1252 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1253 if(tp
->type
== ENUM
) {
1254 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1255 free(tp
->labels
.array
[pos2
]);
1257 sequence_dispose(&(tp
->labels
));
1259 if(tp
->type
== STRUCT
) {
1260 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1261 f
= (field_t
*) tp
->fields
.array
[pos2
];
1263 free(f
->description
);
1266 sequence_dispose(&(tp
->fields
));
1270 void freeNamedType(table_t
* t
)
1273 type_descriptor_t
* td
;
1275 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1276 free((char *)t
->keys
.array
[pos
]);
1277 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1283 void freeTypes(sequence_t
*t
)
1286 type_descriptor_t
*tp
;
1288 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1289 tp
= (type_descriptor_t
*)t
->array
[pos
];
1295 void freeEvents(sequence_t
*t
)
1300 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1301 ev
= (event_t
*) t
->array
[pos
];
1303 free(ev
->description
);
1310 /* Extensible array */
1312 void sequence_init(sequence_t
*t
)
1316 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1319 void sequence_dispose(sequence_t
*t
)
1326 void sequence_push(sequence_t
*t
, void *elem
)
1330 if(t
->position
>= t
->size
) {
1332 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1333 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1334 t
->size
= t
->size
* 2;
1337 t
->array
[t
->position
] = elem
;
1341 void *sequence_pop(sequence_t
*t
)
1343 return t
->array
[t
->position
--];
1347 /* Hash table API, implementation is just linear search for now */
1349 void table_init(table_t
*t
)
1351 sequence_init(&(t
->keys
));
1352 sequence_init(&(t
->values
));
1355 void table_dispose(table_t
*t
)
1357 sequence_dispose(&(t
->keys
));
1358 sequence_dispose(&(t
->values
));
1361 void table_insert(table_t
*t
, char *key
, void *value
)
1363 sequence_push(&(t
->keys
),key
);
1364 sequence_push(&(t
->values
),value
);
1367 void *table_find(table_t
*t
, char *key
)
1370 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1371 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1372 return(t
->values
.array
[pos
]);
1377 void table_insert_int(table_t
*t
, int *key
, void *value
)
1379 sequence_push(&(t
->keys
),key
);
1380 sequence_push(&(t
->values
),value
);
1383 void *table_find_int(table_t
*t
, int *key
)
1386 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1387 if(*key
== *(int *)t
->keys
.array
[pos
])
1388 return(t
->values
.array
[pos
]);
1394 /* Concatenate strings */
1396 char *appendString(char *s
, char *suffix
)
1399 if(suffix
== NULL
) return s
;
1401 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.123147 seconds and 4 git commands to generate.