3 parser.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2005, Mathieu Desnoyers
7 Copyright (C) 2002, Xianxiu Yang
8 Copyright (C) 2002, Michel Dagenais
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* This program reads the ".xml" event definitions input files
24 and constructs structure for each event.
26 The program uses a very simple tokenizer, called from a hand written
27 recursive descent parser to fill a data structure describing the events.
28 The result is a sequence of events definitions which refer to type
31 A table of named types is maintained to allow refering to types by name
32 when the same type is used at several places. Finally a sequence of
33 all types is maintained to facilitate the freeing of all type
34 information when the processing of an ".xml" file is finished. */
40 #include <linux/errno.h>
47 char *intOutputTypes
[] = {
48 "int8_t", "int16_t", "int32_t", "int64_t" };
50 char *uintOutputTypes
[] = {
51 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
53 char *floatOutputTypes
[] = {
54 "undef", "undef", "float", "double" };
60 void strupper(char *string
)
71 int getSizeindex(unsigned 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 unsigned long long int getSize(parse_file_t
*in
)
101 token
= getToken(in
);
102 if(in
->type
== NUMBER
) {
103 return strtoull(token
, NULL
, 0);
105 in
->error(in
,"incorrect size specification");
109 /*****************************************************************************
111 * error_callback : print out error info
113 * in : input file handle
114 * msg : message to be printed
115 ****************************************************************************/
117 void error_callback(parse_file_t
*in
, char *msg
)
120 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
127 /*****************************************************************************
129 * memAlloc : allocate memory
131 * size : required memory size
133 * void * : pointer to allocate memory or NULL
134 ****************************************************************************/
136 void * memAlloc(int size
)
139 if(size
== 0) return NULL
;
142 printf("Failed to allocate memory");
148 /*****************************************************************************
150 * allocAndCopy : allocate memory and initialize it
152 * str : string to be put in memory
154 * char * : pointer to allocate memory or NULL
155 ****************************************************************************/
157 char *allocAndCopy(char *str
)
160 if(str
== NULL
) return NULL
;
161 addr
= (char *)memAlloc(strlen(str
)+1);
166 /**************************************************************************
170 * Read the attribute from the input file.
173 * in , input file handle.
174 * t , the type descriptor to fill.
176 **************************************************************************/
178 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
179 sequence_t
* unnamed_types
, table_t
* named_types
)
188 token
= getToken(in
);
189 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
194 if(!strcmp("format",token
)) {
196 t
->fmt
= allocAndCopy(getQuotedString(in
));
197 //} else if(!strcmp("name",token)) {
199 // car = seekNextChar(in);
200 // if(car == EOF) in->error(in,"name was expected");
201 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
202 // else t->type_name = allocAndCopy(getName(in));
203 } else if(!strcmp("size",token
)) {
205 t
->size
= getSize(in
);
206 } else if(!strcmp("align",token
)) {
208 t
->alignment
= getNumber(in
);
213 /**************************************************************************
217 * Read the attribute from the input file.
220 * in , input file handle.
221 * ev , the event to fill.
223 **************************************************************************/
225 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
232 ev
->per_tracefile
= 0;
235 token
= getToken(in
);
236 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
241 if(!strcmp("name",token
)) {
243 car
= seekNextChar(in
);
244 if(car
== EOF
) in
->error(in
,"name was expected");
245 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
246 else ev
->name
= allocAndCopy(getName(in
));
247 } else if(!strcmp("per_trace", token
)) {
249 } else if(!strcmp("per_tracefile", token
)) {
250 ev
->per_tracefile
= 1;
256 /**************************************************************************
258 * getFacilityAttributes
260 * Read the attribute from the input file.
263 * in , input file handle.
264 * fac , the facility to fill.
266 **************************************************************************/
268 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
276 token
= getToken(in
);
277 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
282 if(!strcmp("name",token
)) {
284 car
= seekNextChar(in
);
285 if(car
== EOF
) in
->error(in
,"name was expected");
286 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
287 else fac
->name
= allocAndCopy(getName(in
));
292 /**************************************************************************
296 * Read the attribute from the input file.
299 * in , input file handle.
300 * f , the field to fill.
302 **************************************************************************/
304 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
312 token
= getToken(in
);
313 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
318 if(!strcmp("name",token
)) {
320 car
= seekNextChar(in
);
321 if(car
== EOF
) in
->error(in
,"name was expected");
322 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
323 else f
->name
= allocAndCopy(getName(in
));
328 char *getNameAttribute(parse_file_t
*in
)
335 token
= getToken(in
);
336 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
341 if(!strcmp("name",token
)) {
343 car
= seekNextChar(in
);
344 if(car
== EOF
) in
->error(in
,"name was expected");
345 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
346 else name
= allocAndCopy(getName(in
));
349 if(name
== NULL
) in
->error(in
, "Name was expected");
356 //for <label name=label_name value=n format="..."/>, value is an option
357 char * getValueStrAttribute(parse_file_t
*in
)
361 token
= getToken(in
);
362 if(strcmp("/",token
) == 0){
367 if(strcmp("value",token
))in
->error(in
,"value was expected");
369 token
= getToken(in
);
370 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
374 char * getDescription(parse_file_t
*in
)
377 char * token
, car
, *str
;
381 getLAnglebracket(in
);
383 if(strcmp("description",token
)){
384 fseek(in
->fp
, pos
, SEEK_SET
);
388 getRAnglebracket(in
);
391 while((car
= getc(in
->fp
)) != EOF
) {
392 if(car
== '<') break;
393 if(car
== '\0') continue;
394 in
->buffer
[pos
] = car
;
397 if(car
== EOF
)in
->error(in
,"not a valid description");
398 in
->buffer
[pos
] = '\0';
400 str
= allocAndCopy(in
->buffer
);
404 if(strcmp("description", token
))in
->error(in
,"not a valid description");
405 getRAnglebracket(in
);
410 /*****************************************************************************
412 * parseFacility : generate event list
414 * in : input file handle
415 * fac : empty facility
417 * fac : facility filled with event list
418 ****************************************************************************/
420 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
425 getFacilityAttributes(in
, fac
);
426 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
428 fac
->capname
= allocAndCopy(fac
->name
);
429 strupper(fac
->capname
);
430 getRAnglebracket(in
);
432 fac
->description
= getDescription(in
);
435 getLAnglebracket(in
);
437 token
= getToken(in
);
438 if(in
->type
== ENDFILE
)
439 in
->error(in
,"the definition of the facility is not finished");
441 if(strcmp("event",token
) == 0){
442 ev
= (event_t
*) memAlloc(sizeof(event_t
));
443 sequence_push(&(fac
->events
),ev
);
444 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
445 }else if(strcmp("type",token
) == 0){
446 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
447 }else if(in
->type
== FORWARDSLASH
){
449 }else in
->error(in
,"event or type token expected\n");
453 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
454 getRAnglebracket(in
); //</facility>
457 /*****************************************************************************
459 * parseEvent : generate event from event definition
461 * in : input file handle
463 * unnamed_types : array of unamed types
464 * named_types : array of named types
466 * ev : new event (parameters are passed to it)
467 ****************************************************************************/
469 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
470 table_t
* named_types
)
475 sequence_init(&(ev
->fields
));
476 //<event name=eventtype_name>
477 getEventAttributes(in
, ev
);
478 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
479 getRAnglebracket(in
);
481 //<description>...</description>
482 ev
->description
= getDescription(in
);
485 /* Events can have multiple fields. each field form at least a function
486 * parameter of the logging function. */
488 getLAnglebracket(in
);
489 token
= getToken(in
);
492 case FORWARDSLASH
: /* </event> */
494 if(strcmp("event",token
))in
->error(in
,"not an event definition");
495 getRAnglebracket(in
); //</event>
498 case NAME
: /* a field */
499 if(strcmp("field",token
))in
->error(in
,"expecting a field");
500 f
= (field_t
*)memAlloc(sizeof(field_t
));
501 sequence_push(&(ev
->fields
),f
);
502 parseFields(in
, f
, unnamed_types
, named_types
, 1);
505 in
->error(in
, "expecting </event> or <field >");
510 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
512 }else if(in
->type
== NAME
){
513 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
515 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
516 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
517 in
->error(in
,"type must be a struct");
518 }else in
->error(in
, "not a valid type");
520 getLAnglebracket(in
);
522 }else in
->error(in
,"not a struct type");
523 getLAnglebracket(in
);
526 if(strcmp("event",token
))in
->error(in
,"not an event definition");
527 getRAnglebracket(in
); //</event>
531 /*****************************************************************************
533 * parseField : get field infomation from buffer
535 * in : input file handle
537 * unnamed_types : array of unamed types
538 * named_types : array of named types
539 * tag : is field surrounded by a <field> </field> tag ?
540 ****************************************************************************/
542 void parseFields(parse_file_t
*in
, field_t
*f
,
543 sequence_t
* unnamed_types
,
544 table_t
* named_types
,
549 //<field name=field_name> <description> <type> </field>
550 getFieldAttributes(in
, f
);
551 if(f
->name
== NULL
) in
->error(in
, "Field not named");
552 getRAnglebracket(in
);
554 f
->description
= getDescription(in
);
558 getLAnglebracket(in
);
559 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
561 /* Those will be set later by preset_field_type_size */
562 f
->fixed_root
= FIELD_UNKNOWN
;
563 f
->fixed_parent
= FIELD_UNKNOWN
;
564 f
->fixed_size
= FIELD_UNKNOWN
;
567 getLAnglebracket(in
);
570 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
571 getRAnglebracket(in
); //</field>
576 /*****************************************************************************
578 * parseType : get type information, type can be :
580 * int(size,fmt); uint(size,fmt); float(size,fmt);
581 * string(fmt); enum(size,fmt,(label1,label2...))
583 * array(arraySize, type); sequence(lengthSize,type)
584 * struct(field(name,type,description)...)
588 * in : input file handle
589 * inType : a type descriptor
590 * unnamed_types : array of unamed types
591 * named_types : array of named types
593 * type_descriptor* : a type descriptor
594 ****************************************************************************/
596 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
597 sequence_t
* unnamed_types
, table_t
* named_types
)
600 type_descriptor_t
*t
;
604 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
608 sequence_push(unnamed_types
,t
);
614 if(strcmp(token
,"struct") == 0) {
616 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
617 getRAnglebracket(in
); //<struct>
618 getLAnglebracket(in
); //<field name=..>
619 token
= getToken(in
);
620 sequence_init(&(t
->fields
));
621 while(strcmp("field",token
) == 0){
622 f
= (field_t
*)memAlloc(sizeof(field_t
));
623 sequence_push(&(t
->fields
),f
);
625 parseFields(in
, f
, unnamed_types
, named_types
, 1);
628 getLAnglebracket(in
);
629 token
= getToken(in
);
631 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
633 if(strcmp("struct",token
)!=0)
634 in
->error(in
,"not a valid structure definition");
635 getRAnglebracket(in
); //</struct>
637 else if(strcmp(token
,"union") == 0) {
639 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
640 getRAnglebracket(in
); //<union>
642 getLAnglebracket(in
); //<field name=..>
643 token
= getToken(in
);
644 sequence_init(&(t
->fields
));
645 while(strcmp("field",token
) == 0){
646 f
= (field_t
*)memAlloc(sizeof(field_t
));
647 sequence_push(&(t
->fields
),f
);
648 parseFields(in
, f
, unnamed_types
, named_types
, 1);
651 getLAnglebracket(in
);
652 token
= getToken(in
);
654 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
656 if(strcmp("union",token
)!=0)
657 in
->error(in
,"not a valid union definition");
658 getRAnglebracket(in
); //</union>
660 else if(strcmp(token
,"array") == 0) {
662 sequence_init(&(t
->fields
));
663 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
664 if(t
->size
== 0) in
->error(in
, "Array has empty size");
666 getRAnglebracket(in
); //<array size=n>
668 getLAnglebracket(in
); //<subtype>
670 f
= (field_t
*)memAlloc(sizeof(field_t
));
671 sequence_push(&(t
->fields
),f
);
672 parseFields(in
, f
, unnamed_types
, named_types
, 0);
674 //getLAnglebracket(in); //<type struct>
675 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
677 getLAnglebracket(in
); //</array>
680 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
681 getRAnglebracket(in
); //</array>
683 else if(strcmp(token
,"sequence") == 0) {
685 sequence_init(&(t
->fields
));
686 //getTypeAttributes(in, t, unnamed_types, named_types);
687 //getForwardslash(in);
688 getRAnglebracket(in
); //<sequence>
690 getLAnglebracket(in
); //<sequence size type>
692 f
= (field_t
*)memAlloc(sizeof(field_t
));
693 sequence_push(&(t
->fields
),f
);
694 parseFields(in
, f
, unnamed_types
, named_types
, 0);
696 getLAnglebracket(in
); //<subtype>
698 f
= (field_t
*)memAlloc(sizeof(field_t
));
699 sequence_push(&(t
->fields
),f
);
700 parseFields(in
, f
, unnamed_types
, named_types
, 0);
702 //getLAnglebracket(in); //<type sequence>
703 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
705 //getLAnglebracket(in); //<type sequence>
707 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
709 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
710 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
711 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
721 in
->error(in
, "Wrong length type for sequence");
724 getLAnglebracket(in
); //</sequence>
727 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
728 getRAnglebracket(in
); //</sequence>
730 else if(strcmp(token
,"enum") == 0) {
733 sequence_init(&(t
->labels
));
734 sequence_init(&(t
->labels_description
));
735 t
->already_printed
= 0;
736 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
737 //if(t->size == 0) in->error(in, "Sequence has empty size");
738 //Mathieu : we fix enum size to 4 bytes. GCC is always like this.
739 //fox copy optimisation.
740 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of 4.");
742 getRAnglebracket(in
);
744 //<label name=label1 value=n/>
745 getLAnglebracket(in
);
746 token
= getToken(in
); //"label" or "/"
747 while(strcmp("label",token
) == 0){
748 str
= allocAndCopy(getNameAttribute(in
));
749 token
= getValueStrAttribute(in
);
751 str1
= appendString(str
,"=");
753 str
= appendString(str1
,token
);
755 sequence_push(&(t
->labels
),str
);
758 sequence_push(&(t
->labels
),str
);
761 getRAnglebracket(in
);
763 //read description if any. May be NULL.
764 str
= allocAndCopy(getDescription(in
));
765 sequence_push(&(t
->labels_description
),str
);
767 //next label definition
768 getLAnglebracket(in
);
769 token
= getToken(in
); //"label" or "/"
771 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
773 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
774 getRAnglebracket(in
); //</label>
776 else if(strcmp(token
,"int_fixed") == 0) {
778 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
779 if(t
->size
== 0) in
->error(in
, "int has empty size");
781 getRAnglebracket(in
);
783 else if(strcmp(token
,"uint_fixed") == 0) {
784 t
->type
= UINT_FIXED
;
785 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
786 if(t
->size
== 0) in
->error(in
, "uint has empty size");
788 getRAnglebracket(in
);
790 else if(strcmp(token
,"char") == 0) {
793 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
795 getRAnglebracket(in
);
797 else if(strcmp(token
,"uchar") == 0) {
800 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
802 getRAnglebracket(in
);
804 else if(strcmp(token
,"short") == 0) {
807 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
809 getRAnglebracket(in
);
811 else if(strcmp(token
,"ushort") == 0) {
814 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
816 getRAnglebracket(in
);
818 else if(strcmp(token
,"int") == 0) {
820 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
822 getRAnglebracket(in
);
824 else if(strcmp(token
,"uint") == 0) {
826 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
828 getRAnglebracket(in
);
831 else if(strcmp(token
,"pointer") == 0) {
833 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
835 getRAnglebracket(in
);
837 else if(strcmp(token
,"long") == 0) {
839 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
841 getRAnglebracket(in
);
843 else if(strcmp(token
,"ulong") == 0) {
845 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
847 getRAnglebracket(in
);
849 else if(strcmp(token
,"size_t") == 0) {
851 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
853 getRAnglebracket(in
);
855 else if(strcmp(token
,"ssize_t") == 0) {
857 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
859 getRAnglebracket(in
);
861 else if(strcmp(token
,"off_t") == 0) {
863 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
865 getRAnglebracket(in
);
867 else if(strcmp(token
,"float") == 0) {
869 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
871 getRAnglebracket(in
);
873 else if(strcmp(token
,"string") == 0) {
875 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
877 getRAnglebracket(in
);
879 else if(strcmp(token
,"typeref") == 0){
880 // Must be a named type
882 sequence_pop(unnamed_types
);
883 token
= getNameAttribute(in
);
884 t
= find_named_type(token
, named_types
);
885 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
886 getForwardslash(in
); //<typeref name=type_name/>
887 getRAnglebracket(in
);
889 }else in
->error(in
,"not a valid type");
894 /*****************************************************************************
896 * find_named_type : find a named type from hash table
899 * named_types : array of named types
901 * type_descriptor * : a type descriptor
902 *****************************************************************************/
904 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
906 type_descriptor_t
*t
;
908 t
= table_find(named_types
,name
);
910 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
911 t
->type_name
= allocAndCopy(name
);
914 table_insert(named_types
,t
->type_name
,t
);
915 // table_insert(named_types,allocAndCopy(name),t);
920 /*****************************************************************************
922 * parseTypeDefinition : get type information from type definition
924 * in : input file handle
925 * unnamed_types : array of unamed types
926 * named_types : array of named types
927 *****************************************************************************/
929 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
930 table_t
* named_types
)
933 type_descriptor_t
*t
;
935 token
= getNameAttribute(in
);
936 if(token
== NULL
) in
->error(in
, "Type has empty name");
937 t
= find_named_type(token
, named_types
);
939 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
940 getRAnglebracket(in
); //<type name=type_name>
941 getLAnglebracket(in
); //<
943 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
945 parseType(in
,t
, unnamed_types
, named_types
);
948 getLAnglebracket(in
);
951 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
952 getRAnglebracket(in
); //</type>
955 /**************************************************************************
957 * getComa, getName, getNumber, getEqual
959 * Read a token from the input file, check its type, return it scontent.
962 * in , input file handle.
965 * address of token content.
967 **************************************************************************/
969 char *getName(parse_file_t
* in
)
973 token
= getToken(in
);
974 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
978 int getNumber(parse_file_t
* in
)
982 token
= getToken(in
);
983 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
987 char *getForwardslash(parse_file_t
* in
)
991 token
= getToken(in
);
992 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
993 /* Mathieu : final / is optional now. */
994 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
999 char *getLAnglebracket(parse_file_t
* in
)
1003 token
= getToken(in
);
1004 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1008 char *getRAnglebracket(parse_file_t
* in
)
1012 token
= getToken(in
);
1013 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1017 char *getQuotedString(parse_file_t
* in
)
1021 token
= getToken(in
);
1022 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1026 char * getEqual(parse_file_t
*in
)
1030 token
= getToken(in
);
1031 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1035 char seekNextChar(parse_file_t
*in
)
1038 while((car
= getc(in
->fp
)) != EOF
) {
1047 /******************************************************************
1049 * getToken, ungetToken
1051 * Read a token from the input file and return its type and content.
1052 * Line numbers are accounted for and whitespace/comments are skipped.
1055 * in, input file handle.
1058 * address of token content.
1060 ******************************************************************/
1062 void ungetToken(parse_file_t
* in
)
1067 char *getToken(parse_file_t
* in
)
1071 int pos
= 0, escaped
;
1073 if(in
->unget
== 1) {
1078 /* skip whitespace and comments */
1080 while((car
= getc(fp
)) != EOF
) {
1083 if(car1
== '*') skipComment(in
);
1084 else if(car1
== '/') skipEOL(in
);
1086 car1
= ungetc(car1
,fp
);
1090 else if(car
== '\n') in
->lineno
++;
1091 else if(!isspace(car
)) break;
1099 in
->type
= FORWARDSLASH
;
1100 in
->buffer
[pos
] = car
;
1104 in
->type
= LANGLEBRACKET
;
1105 in
->buffer
[pos
] = car
;
1109 in
->type
= RANGLEBRACKET
;
1110 in
->buffer
[pos
] = car
;
1115 in
->buffer
[pos
] = car
;
1120 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1121 if(car
== '\\' && escaped
== 0) {
1122 in
->buffer
[pos
] = car
;
1127 if(car
== '"' && escaped
== 0) break;
1128 if(car
== '\n' && escaped
== 0) {
1129 in
->error(in
, "non escaped newline inside quoted string");
1131 if(car
== '\n') in
->lineno
++;
1132 in
->buffer
[pos
] = car
;
1136 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1137 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1138 in
->type
= QUOTEDSTRING
;
1142 in
->buffer
[pos
] = car
;
1144 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1149 in
->buffer
[pos
] = car
;
1152 if(car
== EOF
) ungetc(car
,fp
);
1153 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1156 else if(isalpha(car
)) {
1157 in
->buffer
[0] = car
;
1159 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1160 if(!(isalnum(car
) || car
== '_')) {
1164 in
->buffer
[pos
] = car
;
1167 if(car
== EOF
) ungetc(car
,fp
);
1168 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1171 else in
->error(in
, "invalid character, unrecognized token");
1173 in
->buffer
[pos
] = 0;
1177 void skipComment(parse_file_t
* in
)
1180 while((car
= getc(in
->fp
)) != EOF
) {
1181 if(car
== '\n') in
->lineno
++;
1182 else if(car
== '*') {
1184 if(car
==EOF
) break;
1185 if(car
== '/') return;
1189 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1192 void skipEOL(parse_file_t
* in
)
1195 while((car
= getc(in
->fp
)) != EOF
) {
1201 if(car
== EOF
)ungetc(car
, in
->fp
);
1204 /*****************************************************************************
1206 * checkNamedTypesImplemented : check if all named types have definition
1207 ****************************************************************************/
1209 void checkNamedTypesImplemented(table_t
* named_types
)
1211 type_descriptor_t
*t
;
1215 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1216 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1217 if(t
->type
== NONE
){
1218 sprintf(str
,"named type '%s' has no definition",
1219 (char*)named_types
->keys
.array
[pos
]);
1220 error_callback(NULL
,str
);
1226 /*****************************************************************************
1228 * generateChecksum : generate checksum for the facility
1230 * facName : name of facility
1232 * checksum : checksum for the facility
1233 ****************************************************************************/
1235 void generateChecksum(char* facName
,
1236 unsigned long * checksum
, sequence_t
* events
)
1242 crc
= crc32(facName
);
1243 for(pos
= 0; pos
< events
->position
; pos
++){
1244 ev
= (event_t
*)(events
->array
[pos
]);
1245 crc
= partial_crc32(ev
->name
, crc
);
1246 for(unsigned int i
= 0; i
< ev
->fields
.position
; i
++) {
1247 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1248 crc
= partial_crc32(f
->name
, crc
);
1249 crc
= getTypeChecksum(crc
, f
->type
);
1255 /*****************************************************************************
1257 * getTypeChecksum : generate checksum by type info
1259 * crc : checksum generated so far
1260 * type : type descriptor containing type info
1262 * unsigned long : checksum
1263 *****************************************************************************/
1265 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1267 unsigned long crc
= aCrc
;
1268 char * str
= NULL
, buf
[16];
1274 str
= intOutputTypes
[getSizeindex(type
->size
)];
1277 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1280 str
= allocAndCopy("void *");
1284 str
= allocAndCopy("signed char");
1288 str
= allocAndCopy("unsigned char");
1292 str
= allocAndCopy("short");
1296 str
= allocAndCopy("unsigned short");
1300 str
= allocAndCopy("int");
1304 str
= allocAndCopy("uint");
1308 str
= allocAndCopy("long");
1312 str
= allocAndCopy("unsigned long");
1316 str
= allocAndCopy("size_t");
1320 str
= allocAndCopy("ssize_t");
1324 str
= allocAndCopy("off_t");
1328 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1331 str
= allocAndCopy("string");
1335 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1336 str
= allocAndCopy("enum");
1340 sprintf(buf
,"%llu", type
->size
);
1341 str
= appendString("array ",buf
);
1345 sprintf(buf
,"%llu", type
->size
);
1346 str
= appendString("sequence ",buf
);
1350 str
= allocAndCopy("struct");
1354 str
= allocAndCopy("union");
1358 error_callback(NULL
, "named type has no definition");
1362 crc
= partial_crc32(str
,crc
);
1365 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1367 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1368 crc
= getTypeChecksum(crc
,type
->nested_type
);
1369 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1370 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1371 fld
= (field_t
*) type
->fields
.array
[pos
];
1372 crc
= partial_crc32(fld
->name
,crc
);
1373 crc
= getTypeChecksum(crc
, fld
->type
);
1375 }else if(type
->type
== ENUM
){
1376 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1377 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1384 /* Event type descriptors */
1385 void freeType(type_descriptor_t
* tp
)
1390 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1391 if(tp
->type
== ENUM
) {
1392 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1393 free(tp
->labels
.array
[pos2
]);
1395 sequence_dispose(&(tp
->labels
));
1397 if(tp
->type
== STRUCT
) {
1398 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1399 f
= (field_t
*) tp
->fields
.array
[pos2
];
1401 free(f
->description
);
1404 sequence_dispose(&(tp
->fields
));
1408 void freeNamedType(table_t
* t
)
1411 type_descriptor_t
* td
;
1413 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1414 free((char *)t
->keys
.array
[pos
]);
1415 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1421 void freeTypes(sequence_t
*t
)
1424 type_descriptor_t
*tp
;
1426 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1427 tp
= (type_descriptor_t
*)t
->array
[pos
];
1433 void freeEvents(sequence_t
*t
)
1438 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1439 ev
= (event_t
*) t
->array
[pos
];
1441 free(ev
->description
);
1442 sequence_dispose(&ev
->fields
);
1449 /* Extensible array */
1451 void sequence_init(sequence_t
*t
)
1455 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1458 void sequence_dispose(sequence_t
*t
)
1465 void sequence_push(sequence_t
*t
, void *elem
)
1469 if(t
->position
>= t
->size
) {
1471 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1472 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1473 t
->size
= t
->size
* 2;
1476 t
->array
[t
->position
] = elem
;
1480 void *sequence_pop(sequence_t
*t
)
1482 return t
->array
[t
->position
--];
1486 /* Hash table API, implementation is just linear search for now */
1488 void table_init(table_t
*t
)
1490 sequence_init(&(t
->keys
));
1491 sequence_init(&(t
->values
));
1494 void table_dispose(table_t
*t
)
1496 sequence_dispose(&(t
->keys
));
1497 sequence_dispose(&(t
->values
));
1500 void table_insert(table_t
*t
, char *key
, void *value
)
1502 sequence_push(&(t
->keys
),key
);
1503 sequence_push(&(t
->values
),value
);
1506 void *table_find(table_t
*t
, char *key
)
1509 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1510 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1511 return(t
->values
.array
[pos
]);
1516 void table_insert_int(table_t
*t
, int *key
, void *value
)
1518 sequence_push(&(t
->keys
),key
);
1519 sequence_push(&(t
->values
),value
);
1522 void *table_find_int(table_t
*t
, int *key
)
1525 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1526 if(*key
== *(int *)t
->keys
.array
[pos
])
1527 return(t
->values
.array
[pos
]);
1533 /* Concatenate strings */
1535 char *appendString(char *s
, char *suffix
)
1538 if(suffix
== NULL
) return s
;
1540 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.096362 seconds and 4 git commands to generate.