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
)
187 token
= getToken(in
);
188 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
193 if(!strcmp("format",token
)) {
195 t
->fmt
= allocAndCopy(getQuotedString(in
));
196 //} else if(!strcmp("name",token)) {
198 // car = seekNextChar(in);
199 // if(car == EOF) in->error(in,"name was expected");
200 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
201 // else t->type_name = allocAndCopy(getName(in));
202 } else if(!strcmp("size",token
)) {
204 t
->size
= getSize(in
);
209 /**************************************************************************
213 * Read the attribute from the input file.
216 * in , input file handle.
217 * ev , the event to fill.
219 **************************************************************************/
221 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
228 ev
->per_tracefile
= 0;
231 token
= getToken(in
);
232 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
237 if(!strcmp("name",token
)) {
239 car
= seekNextChar(in
);
240 if(car
== EOF
) in
->error(in
,"name was expected");
241 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
242 else ev
->name
= allocAndCopy(getName(in
));
243 } else if(!strcmp("per_trace", token
)) {
245 } else if(!strcmp("per_tracefile", token
)) {
246 ev
->per_tracefile
= 1;
252 /**************************************************************************
254 * getFacilityAttributes
256 * Read the attribute from the input file.
259 * in , input file handle.
260 * fac , the facility to fill.
262 **************************************************************************/
264 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
272 token
= getToken(in
);
273 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
278 if(!strcmp("name",token
)) {
280 car
= seekNextChar(in
);
281 if(car
== EOF
) in
->error(in
,"name was expected");
282 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
283 else fac
->name
= allocAndCopy(getName(in
));
288 /**************************************************************************
292 * Read the attribute from the input file.
295 * in , input file handle.
296 * f , the field to fill.
298 **************************************************************************/
300 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
308 token
= getToken(in
);
309 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
314 if(!strcmp("name",token
)) {
316 car
= seekNextChar(in
);
317 if(car
== EOF
) in
->error(in
,"name was expected");
318 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
319 else f
->name
= allocAndCopy(getName(in
));
324 char *getNameAttribute(parse_file_t
*in
)
331 token
= getToken(in
);
332 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
337 if(!strcmp("name",token
)) {
339 car
= seekNextChar(in
);
340 if(car
== EOF
) in
->error(in
,"name was expected");
341 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
342 else name
= allocAndCopy(getName(in
));
345 if(name
== NULL
) in
->error(in
, "Name was expected");
352 //for <label name=label_name value=n format="..."/>, value is an option
353 char * getValueStrAttribute(parse_file_t
*in
)
357 token
= getToken(in
);
358 if(strcmp("/",token
) == 0){
363 if(strcmp("value",token
))in
->error(in
,"value was expected");
365 token
= getToken(in
);
366 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
370 char * getDescription(parse_file_t
*in
)
373 char * token
, car
, *str
;
377 getLAnglebracket(in
);
379 if(strcmp("description",token
)){
380 fseek(in
->fp
, pos
, SEEK_SET
);
384 getRAnglebracket(in
);
387 while((car
= getc(in
->fp
)) != EOF
) {
388 if(car
== '<') break;
389 if(car
== '\0') continue;
390 in
->buffer
[pos
] = car
;
393 if(car
== EOF
)in
->error(in
,"not a valid description");
394 in
->buffer
[pos
] = '\0';
396 str
= allocAndCopy(in
->buffer
);
400 if(strcmp("description", token
))in
->error(in
,"not a valid description");
401 getRAnglebracket(in
);
406 /*****************************************************************************
408 * parseFacility : generate event list
410 * in : input file handle
411 * fac : empty facility
413 * fac : facility filled with event list
414 ****************************************************************************/
416 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
421 getFacilityAttributes(in
, fac
);
422 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
424 fac
->capname
= allocAndCopy(fac
->name
);
425 strupper(fac
->capname
);
426 getRAnglebracket(in
);
428 fac
->description
= getDescription(in
);
431 getLAnglebracket(in
);
433 token
= getToken(in
);
434 if(in
->type
== ENDFILE
)
435 in
->error(in
,"the definition of the facility is not finished");
437 if(strcmp("event",token
) == 0){
438 ev
= (event_t
*) memAlloc(sizeof(event_t
));
439 sequence_push(&(fac
->events
),ev
);
440 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
441 }else if(strcmp("type",token
) == 0){
442 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
443 }else if(in
->type
== FORWARDSLASH
){
445 }else in
->error(in
,"event or type token expected\n");
449 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
450 getRAnglebracket(in
); //</facility>
453 /*****************************************************************************
455 * parseEvent : generate event from event definition
457 * in : input file handle
459 * unnamed_types : array of unamed types
460 * named_types : array of named types
462 * ev : new event (parameters are passed to it)
463 ****************************************************************************/
465 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
466 table_t
* named_types
)
471 sequence_init(&(ev
->fields
));
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>...</description>
478 ev
->description
= getDescription(in
);
481 /* Events can have multiple fields. each field form at least a function
482 * parameter of the logging function. */
484 getLAnglebracket(in
);
485 token
= getToken(in
);
488 case FORWARDSLASH
: /* </event> */
490 if(strcmp("event",token
))in
->error(in
,"not an event definition");
491 getRAnglebracket(in
); //</event>
494 case NAME
: /* a field */
495 if(strcmp("field",token
))in
->error(in
,"expecting a field");
496 f
= (field_t
*)memAlloc(sizeof(field_t
));
497 sequence_push(&(ev
->fields
),f
);
498 parseFields(in
, f
, unnamed_types
, named_types
, 1);
501 in
->error(in
, "expecting </event> or <field >");
506 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
508 }else if(in
->type
== NAME
){
509 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
511 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
512 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
513 in
->error(in
,"type must be a struct");
514 }else in
->error(in
, "not a valid type");
516 getLAnglebracket(in
);
518 }else in
->error(in
,"not a struct type");
519 getLAnglebracket(in
);
522 if(strcmp("event",token
))in
->error(in
,"not an event definition");
523 getRAnglebracket(in
); //</event>
527 /*****************************************************************************
529 * parseField : get field infomation from buffer
531 * in : input file handle
533 * unnamed_types : array of unamed types
534 * named_types : array of named types
535 * tag : is field surrounded by a <field> </field> tag ?
536 ****************************************************************************/
538 void parseFields(parse_file_t
*in
, field_t
*f
,
539 sequence_t
* unnamed_types
,
540 table_t
* named_types
,
545 //<field name=field_name> <description> <type> </field>
546 getFieldAttributes(in
, f
);
547 if(f
->name
== NULL
) in
->error(in
, "Field not named");
548 getRAnglebracket(in
);
550 f
->description
= getDescription(in
);
554 getLAnglebracket(in
);
555 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
558 getLAnglebracket(in
);
561 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
562 getRAnglebracket(in
); //</field>
567 /*****************************************************************************
569 * parseType : get type information, type can be :
571 * int(size,fmt); uint(size,fmt); float(size,fmt);
572 * string(fmt); enum(size,fmt,(label1,label2...))
574 * array(arraySize, type); sequence(lengthSize,type)
575 * struct(field(name,type,description)...)
579 * in : input file handle
580 * inType : a type descriptor
581 * unnamed_types : array of unamed types
582 * named_types : array of named types
584 * type_descriptor* : a type descriptor
585 ****************************************************************************/
587 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
588 sequence_t
* unnamed_types
, table_t
* named_types
)
591 type_descriptor_t
*t
;
595 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
599 sequence_push(unnamed_types
,t
);
605 if(strcmp(token
,"struct") == 0) {
607 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
608 getRAnglebracket(in
); //<struct>
609 getLAnglebracket(in
); //<field name=..>
610 token
= getToken(in
);
611 sequence_init(&(t
->fields
));
612 while(strcmp("field",token
) == 0){
613 f
= (field_t
*)memAlloc(sizeof(field_t
));
614 sequence_push(&(t
->fields
),f
);
616 parseFields(in
, f
, unnamed_types
, named_types
, 1);
619 getLAnglebracket(in
);
620 token
= getToken(in
);
622 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
624 if(strcmp("struct",token
)!=0)
625 in
->error(in
,"not a valid structure definition");
626 getRAnglebracket(in
); //</struct>
628 else if(strcmp(token
,"union") == 0) {
630 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
631 getRAnglebracket(in
); //<union>
633 getLAnglebracket(in
); //<field name=..>
634 token
= getToken(in
);
635 sequence_init(&(t
->fields
));
636 while(strcmp("field",token
) == 0){
637 f
= (field_t
*)memAlloc(sizeof(field_t
));
638 sequence_push(&(t
->fields
),f
);
639 parseFields(in
, f
, unnamed_types
, named_types
, 1);
642 getLAnglebracket(in
);
643 token
= getToken(in
);
645 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
647 if(strcmp("union",token
)!=0)
648 in
->error(in
,"not a valid union definition");
649 getRAnglebracket(in
); //</union>
651 else if(strcmp(token
,"array") == 0) {
653 sequence_init(&(t
->fields
));
654 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
655 if(t
->size
== 0) in
->error(in
, "Array has empty size");
657 getRAnglebracket(in
); //<array size=n>
659 //getLAnglebracket(in); //<subtype>
661 f
= (field_t
*)memAlloc(sizeof(field_t
));
662 sequence_push(&(t
->fields
),f
);
663 parseFields(in
, f
, unnamed_types
, named_types
, 0);
665 //getLAnglebracket(in); //<type struct>
666 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
668 getLAnglebracket(in
); //</array>
671 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
672 getRAnglebracket(in
); //</array>
674 else if(strcmp(token
,"sequence") == 0) {
676 sequence_init(&(t
->fields
));
677 //getTypeAttributes(in, t, unnamed_types, named_types);
678 //getForwardslash(in);
679 getRAnglebracket(in
); //<sequence>
681 //getLAnglebracket(in); //<sequence size type>
683 f
= (field_t
*)memAlloc(sizeof(field_t
));
684 sequence_push(&(t
->fields
),f
);
685 parseFields(in
, f
, unnamed_types
, named_types
, 0);
687 //getLAnglebracket(in); //<subtype>
689 f
= (field_t
*)memAlloc(sizeof(field_t
));
690 sequence_push(&(t
->fields
),f
);
691 parseFields(in
, f
, unnamed_types
, named_types
, 0);
693 //getLAnglebracket(in); //<type sequence>
694 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
696 //getLAnglebracket(in); //<type sequence>
698 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
700 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
701 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
702 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
712 in
->error(in
, "Wrong length type for sequence");
715 getLAnglebracket(in
); //</sequence>
718 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
719 getRAnglebracket(in
); //</sequence>
721 else if(strcmp(token
,"enum") == 0) {
726 sequence_init(&(t
->labels
));
727 sequence_init(&(t
->labels_values
));
728 sequence_init(&(t
->labels_description
));
729 t
->already_printed
= 0;
730 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
731 //if(t->size == 0) in->error(in, "Sequence has empty size");
732 //Mathieu : we fix enum size to target int size. GCC is always like this.
733 //fox copy optimisation.
734 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
736 getRAnglebracket(in
);
738 //<label name=label1 value=n/>
739 getLAnglebracket(in
);
740 token
= getToken(in
); //"label" or "/"
741 while(strcmp("label",token
) == 0){
742 int *label_value
= malloc(sizeof(int));
744 str
= allocAndCopy(getNameAttribute(in
));
745 token
= getValueStrAttribute(in
);
747 sequence_push(&(t
->labels
),str
);
749 if(token
) value
= strtol(token
, NULL
, 0);
752 *label_value
= value
;
753 sequence_push(&(t
->labels_values
), label_value
);
756 getRAnglebracket(in
);
758 //read description if any. May be NULL.
759 str
= allocAndCopy(getDescription(in
));
760 sequence_push(&(t
->labels_description
),str
);
762 //next label definition
763 getLAnglebracket(in
);
764 token
= getToken(in
); //"label" or "/"
766 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
768 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
769 getRAnglebracket(in
); //</label>
771 else if(strcmp(token
,"int_fixed") == 0) {
773 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
774 if(t
->size
== 0) in
->error(in
, "int has empty size");
776 getRAnglebracket(in
);
778 else if(strcmp(token
,"uint_fixed") == 0) {
779 t
->type
= UINT_FIXED
;
780 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
781 if(t
->size
== 0) in
->error(in
, "uint has empty size");
783 getRAnglebracket(in
);
785 else if(strcmp(token
,"char") == 0) {
787 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
790 getRAnglebracket(in
);
792 else if(strcmp(token
,"uchar") == 0) {
794 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
797 getRAnglebracket(in
);
799 else if(strcmp(token
,"short") == 0) {
801 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
804 getRAnglebracket(in
);
806 else if(strcmp(token
,"ushort") == 0) {
808 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
811 getRAnglebracket(in
);
813 else if(strcmp(token
,"int") == 0) {
815 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
817 getRAnglebracket(in
);
819 else if(strcmp(token
,"uint") == 0) {
821 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
823 getRAnglebracket(in
);
826 else if(strcmp(token
,"pointer") == 0) {
828 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
830 getRAnglebracket(in
);
832 else if(strcmp(token
,"long") == 0) {
834 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
836 getRAnglebracket(in
);
838 else if(strcmp(token
,"ulong") == 0) {
840 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
842 getRAnglebracket(in
);
844 else if(strcmp(token
,"size_t") == 0) {
846 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
848 getRAnglebracket(in
);
850 else if(strcmp(token
,"ssize_t") == 0) {
852 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
854 getRAnglebracket(in
);
856 else if(strcmp(token
,"off_t") == 0) {
858 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
860 getRAnglebracket(in
);
862 else if(strcmp(token
,"float") == 0) {
864 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
866 getRAnglebracket(in
);
868 else if(strcmp(token
,"string") == 0) {
870 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
872 getRAnglebracket(in
);
874 else if(strcmp(token
,"typeref") == 0){
875 // Must be a named type
877 sequence_pop(unnamed_types
);
878 token
= getNameAttribute(in
);
879 t
= find_named_type(token
, named_types
);
880 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
881 getForwardslash(in
); //<typeref name=type_name/>
882 getRAnglebracket(in
);
884 }else in
->error(in
,"not a valid type");
889 /*****************************************************************************
891 * find_named_type : find a named type from hash table
894 * named_types : array of named types
896 * type_descriptor * : a type descriptor
897 *****************************************************************************/
899 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
901 type_descriptor_t
*t
;
903 t
= table_find(named_types
,name
);
908 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
910 type_descriptor_t
*t
;
912 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
913 t
->type_name
= allocAndCopy(name
);
916 table_insert(named_types
,t
->type_name
,t
);
917 // table_insert(named_types,allocAndCopy(name),t);
921 /*****************************************************************************
923 * parseTypeDefinition : get type information from type definition
925 * in : input file handle
926 * unnamed_types : array of unamed types
927 * named_types : array of named types
928 *****************************************************************************/
930 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
931 table_t
* named_types
)
934 type_descriptor_t
*t
;
936 token
= getNameAttribute(in
);
937 if(token
== NULL
) in
->error(in
, "Type has empty name");
938 t
= create_named_type(token
, named_types
);
940 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
941 getRAnglebracket(in
); //<type name=type_name>
942 getLAnglebracket(in
); //<
944 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
946 parseType(in
,t
, unnamed_types
, named_types
);
949 getLAnglebracket(in
);
952 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
953 getRAnglebracket(in
); //</type>
956 /**************************************************************************
958 * getComa, getName, getNumber, getEqual
960 * Read a token from the input file, check its type, return it scontent.
963 * in , input file handle.
966 * address of token content.
968 **************************************************************************/
970 char *getName(parse_file_t
* in
)
974 token
= getToken(in
);
975 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
979 int getNumber(parse_file_t
* in
)
983 token
= getToken(in
);
984 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
988 char *getForwardslash(parse_file_t
* in
)
992 token
= getToken(in
);
993 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
994 /* Mathieu : final / is optional now. */
995 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1000 char *getLAnglebracket(parse_file_t
* in
)
1004 token
= getToken(in
);
1005 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1009 char *getRAnglebracket(parse_file_t
* in
)
1013 token
= getToken(in
);
1014 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1018 char *getQuotedString(parse_file_t
* in
)
1022 token
= getToken(in
);
1023 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1027 char * getEqual(parse_file_t
*in
)
1031 token
= getToken(in
);
1032 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1036 char seekNextChar(parse_file_t
*in
)
1039 while((car
= getc(in
->fp
)) != EOF
) {
1048 /******************************************************************
1050 * getToken, ungetToken
1052 * Read a token from the input file and return its type and content.
1053 * Line numbers are accounted for and whitespace/comments are skipped.
1056 * in, input file handle.
1059 * address of token content.
1061 ******************************************************************/
1063 void ungetToken(parse_file_t
* in
)
1068 char *getToken(parse_file_t
* in
)
1072 int pos
= 0, escaped
;
1074 if(in
->unget
== 1) {
1079 /* skip whitespace and comments */
1081 while((car
= getc(fp
)) != EOF
) {
1084 if(car1
== '*') skipComment(in
);
1085 else if(car1
== '/') skipEOL(in
);
1087 car1
= ungetc(car1
,fp
);
1091 else if(car
== '\n') in
->lineno
++;
1092 else if(!isspace(car
)) break;
1100 in
->type
= FORWARDSLASH
;
1101 in
->buffer
[pos
] = car
;
1105 in
->type
= LANGLEBRACKET
;
1106 in
->buffer
[pos
] = car
;
1110 in
->type
= RANGLEBRACKET
;
1111 in
->buffer
[pos
] = car
;
1116 in
->buffer
[pos
] = car
;
1121 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1122 if(car
== '\\' && escaped
== 0) {
1123 in
->buffer
[pos
] = car
;
1128 if(car
== '"' && escaped
== 0) break;
1129 if(car
== '\n' && escaped
== 0) {
1130 in
->error(in
, "non escaped newline inside quoted string");
1132 if(car
== '\n') in
->lineno
++;
1133 in
->buffer
[pos
] = car
;
1137 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1138 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1139 in
->type
= QUOTEDSTRING
;
1143 in
->buffer
[pos
] = car
;
1145 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1150 in
->buffer
[pos
] = car
;
1153 if(car
== EOF
) ungetc(car
,fp
);
1154 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1157 else if(isalpha(car
)) {
1158 in
->buffer
[0] = car
;
1160 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1161 if(!(isalnum(car
) || car
== '_')) {
1165 in
->buffer
[pos
] = car
;
1168 if(car
== EOF
) ungetc(car
,fp
);
1169 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1172 else in
->error(in
, "invalid character, unrecognized token");
1174 in
->buffer
[pos
] = 0;
1178 void skipComment(parse_file_t
* in
)
1181 while((car
= getc(in
->fp
)) != EOF
) {
1182 if(car
== '\n') in
->lineno
++;
1183 else if(car
== '*') {
1185 if(car
==EOF
) break;
1186 if(car
== '/') return;
1190 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1193 void skipEOL(parse_file_t
* in
)
1196 while((car
= getc(in
->fp
)) != EOF
) {
1202 if(car
== EOF
)ungetc(car
, in
->fp
);
1205 /*****************************************************************************
1207 * checkNamedTypesImplemented : check if all named types have definition
1208 ****************************************************************************/
1210 void checkNamedTypesImplemented(table_t
* named_types
)
1212 type_descriptor_t
*t
;
1216 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1217 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1218 if(t
->type
== NONE
){
1219 sprintf(str
,"named type '%s' has no definition",
1220 (char*)named_types
->keys
.array
[pos
]);
1221 error_callback(NULL
,str
);
1227 /*****************************************************************************
1229 * generateChecksum : generate checksum for the facility
1231 * facName : name of facility
1233 * checksum : checksum for the facility
1234 ****************************************************************************/
1236 void generateChecksum(char* facName
,
1237 unsigned int * checksum
, sequence_t
* events
)
1244 crc
= crc32(facName
);
1245 for(pos
= 0; pos
< events
->position
; pos
++){
1246 ev
= (event_t
*)(events
->array
[pos
]);
1247 crc
= partial_crc32(ev
->name
, crc
);
1248 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1249 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1250 crc
= partial_crc32(f
->name
, crc
);
1251 crc
= getTypeChecksum(crc
, f
->type
);
1257 /*****************************************************************************
1259 * getTypeChecksum : generate checksum by type info
1261 * crc : checksum generated so far
1262 * type : type descriptor containing type info
1264 * unsigned long : checksum
1265 *****************************************************************************/
1267 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1269 unsigned long crc
= aCrc
;
1270 char * str
= NULL
, buf
[16];
1276 str
= intOutputTypes
[getSizeindex(type
->size
)];
1279 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1282 str
= allocAndCopy("void *");
1286 str
= allocAndCopy("signed char");
1290 str
= allocAndCopy("unsigned char");
1294 str
= allocAndCopy("short");
1298 str
= allocAndCopy("unsigned short");
1302 str
= allocAndCopy("int");
1306 str
= allocAndCopy("uint");
1310 str
= allocAndCopy("long");
1314 str
= allocAndCopy("unsigned long");
1318 str
= allocAndCopy("size_t");
1322 str
= allocAndCopy("ssize_t");
1326 str
= allocAndCopy("off_t");
1330 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1333 str
= allocAndCopy("string");
1337 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1338 str
= allocAndCopy("enum");
1342 sprintf(buf
,"%zu", type
->size
);
1343 str
= appendString("array ",buf
);
1347 str
= allocAndCopy("sequence ");
1351 str
= allocAndCopy("struct");
1355 str
= allocAndCopy("union");
1359 error_callback(NULL
, "named type has no definition");
1363 crc
= partial_crc32(str
,crc
);
1366 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1368 if(type
->type
== ARRAY
){
1369 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1370 } else if(type
->type
==SEQUENCE
) {
1371 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1372 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1373 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1374 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1375 fld
= (field_t
*) type
->fields
.array
[pos
];
1376 crc
= partial_crc32(fld
->name
,crc
);
1377 crc
= getTypeChecksum(crc
, fld
->type
);
1379 }else if(type
->type
== ENUM
){
1380 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1381 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1388 /* Event type descriptors */
1389 void freeType(type_descriptor_t
* tp
)
1394 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1395 if(tp
->type
== ENUM
) {
1396 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1397 free(tp
->labels
.array
[pos2
]);
1399 sequence_dispose(&(tp
->labels
));
1400 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1401 free(tp
->labels_values
.array
[pos2
]);
1403 sequence_dispose(&(tp
->labels_values
));
1405 if(tp
->type
== STRUCT
) {
1406 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1407 f
= (field_t
*) tp
->fields
.array
[pos2
];
1409 free(f
->description
);
1412 sequence_dispose(&(tp
->fields
));
1416 void freeNamedType(table_t
* t
)
1419 type_descriptor_t
* td
;
1421 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1422 free((char *)t
->keys
.array
[pos
]);
1423 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1429 void freeTypes(sequence_t
*t
)
1432 type_descriptor_t
*tp
;
1434 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1435 tp
= (type_descriptor_t
*)t
->array
[pos
];
1441 void freeEvents(sequence_t
*t
)
1446 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1447 ev
= (event_t
*) t
->array
[pos
];
1449 free(ev
->description
);
1450 sequence_dispose(&ev
->fields
);
1457 /* Extensible array */
1459 void sequence_init(sequence_t
*t
)
1463 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1466 void sequence_dispose(sequence_t
*t
)
1473 void sequence_push(sequence_t
*t
, void *elem
)
1477 if(t
->position
>= t
->size
) {
1479 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1480 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1481 t
->size
= t
->size
* 2;
1484 t
->array
[t
->position
] = elem
;
1488 void *sequence_pop(sequence_t
*t
)
1490 return t
->array
[t
->position
--];
1494 /* Hash table API, implementation is just linear search for now */
1496 void table_init(table_t
*t
)
1498 sequence_init(&(t
->keys
));
1499 sequence_init(&(t
->values
));
1502 void table_dispose(table_t
*t
)
1504 sequence_dispose(&(t
->keys
));
1505 sequence_dispose(&(t
->values
));
1508 void table_insert(table_t
*t
, char *key
, void *value
)
1510 sequence_push(&(t
->keys
),key
);
1511 sequence_push(&(t
->values
),value
);
1514 void *table_find(table_t
*t
, char *key
)
1517 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1518 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1519 return(t
->values
.array
[pos
]);
1524 void table_insert_int(table_t
*t
, int *key
, void *value
)
1526 sequence_push(&(t
->keys
),key
);
1527 sequence_push(&(t
->values
),value
);
1530 void *table_find_int(table_t
*t
, int *key
)
1533 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1534 if(*key
== *(int *)t
->keys
.array
[pos
])
1535 return(t
->values
.array
[pos
]);
1541 /* Concatenate strings */
1543 char *appendString(char *s
, char *suffix
)
1546 if(suffix
== NULL
) return s
;
1548 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.105141 seconds and 4 git commands to generate.