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
)
189 token
= getToken(in
);
190 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
195 if(!strcmp("format",token
)) {
197 t
->fmt
= allocAndCopy(getQuotedString(in
));
198 //} else if(!strcmp("name",token)) {
200 // car = seekNextChar(in);
201 // if(car == EOF) in->error(in,"name was expected");
202 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
203 // else t->type_name = allocAndCopy(getName(in));
204 } else if(!strcmp("size",token
)) {
206 t
->size
= getSize(in
);
207 } else if(!strcmp("custom_write", token
)) {
209 } else if(!strcmp("network", token
)) {
215 /**************************************************************************
219 * Read the attribute from the input file.
222 * in , input file handle.
223 * ev , the event to fill.
225 **************************************************************************/
227 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
234 ev
->per_tracefile
= 0;
237 token
= getToken(in
);
238 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
243 if(!strcmp("name",token
)) {
245 car
= seekNextChar(in
);
246 if(car
== EOF
) in
->error(in
,"name was expected");
247 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
248 else ev
->name
= allocAndCopy(getName(in
));
249 } else if(!strcmp("per_trace", token
)) {
251 } else if(!strcmp("per_tracefile", token
)) {
252 ev
->per_tracefile
= 1;
258 /**************************************************************************
260 * getFacilityAttributes
262 * Read the attribute from the input file.
265 * in , input file handle.
266 * fac , the facility to fill.
268 **************************************************************************/
270 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
279 token
= getToken(in
);
280 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
285 if(!strcmp("name",token
)) {
287 car
= seekNextChar(in
);
288 if(car
== EOF
) in
->error(in
,"name was expected");
289 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
290 else fac
->name
= allocAndCopy(getName(in
));
291 } else if(!strcmp("arch", token
)) {
293 car
= seekNextChar(in
);
294 if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
295 else fac
->arch
= allocAndCopy(getName(in
));
300 /**************************************************************************
304 * Read the attribute from the input file.
307 * in , input file handle.
308 * f , the field to fill.
310 **************************************************************************/
312 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
320 token
= getToken(in
);
321 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
326 if(!strcmp("name",token
)) {
328 car
= seekNextChar(in
);
329 if(car
== EOF
) in
->error(in
,"name was expected");
330 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
331 else f
->name
= allocAndCopy(getName(in
));
336 char *getNameAttribute(parse_file_t
*in
)
343 token
= getToken(in
);
344 if(!strcmp("name",token
)) {
346 car
= seekNextChar(in
);
347 if(car
== EOF
) in
->error(in
,"name was expected");
348 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
349 else name
= allocAndCopy(getName(in
));
356 if(name
== NULL
) in
->error(in
, "Name was expected");
362 //for <label name=label_name value=n format="..."/>, value is an option
363 char * getValueStrAttribute(parse_file_t
*in
)
367 token
= getToken(in
);
368 if(strcmp("/",token
) == 0){
373 if(strcmp("value",token
))in
->error(in
,"value was expected");
375 token
= getToken(in
);
376 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
380 char * getDescription(parse_file_t
*in
)
383 char * token
, car
, *str
;
387 getLAnglebracket(in
);
389 if(strcmp("description",token
)){
390 fseek(in
->fp
, pos
, SEEK_SET
);
394 getRAnglebracket(in
);
397 while((car
= getc(in
->fp
)) != EOF
) {
398 if(car
== '<') break;
399 if(car
== '\0') continue;
400 in
->buffer
[pos
] = car
;
403 if(car
== EOF
)in
->error(in
,"not a valid description");
404 in
->buffer
[pos
] = '\0';
406 str
= allocAndCopy(in
->buffer
);
410 if(strcmp("description", token
))in
->error(in
,"not a valid description");
411 getRAnglebracket(in
);
416 /*****************************************************************************
418 * parseFacility : generate event list
420 * in : input file handle
421 * fac : empty facility
423 * fac : facility filled with event list
424 ****************************************************************************/
426 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
431 getFacilityAttributes(in
, fac
);
432 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
434 fac
->capname
= allocAndCopy(fac
->name
);
435 strupper(fac
->capname
);
436 getRAnglebracket(in
);
438 fac
->description
= getDescription(in
);
441 getLAnglebracket(in
);
443 token
= getToken(in
);
444 if(in
->type
== ENDFILE
)
445 in
->error(in
,"the definition of the facility is not finished");
447 if(strcmp("event",token
) == 0){
448 ev
= (event_t
*) memAlloc(sizeof(event_t
));
449 sequence_push(&(fac
->events
),ev
);
450 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
451 }else if(strcmp("type",token
) == 0){
452 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
453 }else if(in
->type
== FORWARDSLASH
){
455 }else in
->error(in
,"event or type token expected\n");
459 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
460 getRAnglebracket(in
); //</facility>
463 /*****************************************************************************
465 * parseEvent : generate event from event definition
467 * in : input file handle
469 * unnamed_types : array of unamed types
470 * named_types : array of named types
472 * ev : new event (parameters are passed to it)
473 ****************************************************************************/
475 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
476 table_t
* named_types
)
481 sequence_init(&(ev
->fields
));
482 //<event name=eventtype_name>
483 getEventAttributes(in
, ev
);
484 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
485 getRAnglebracket(in
);
487 //<description>...</description>
488 ev
->description
= getDescription(in
);
491 /* Events can have multiple fields. each field form at least a function
492 * parameter of the logging function. */
494 getLAnglebracket(in
);
495 token
= getToken(in
);
498 case FORWARDSLASH
: /* </event> */
500 if(strcmp("event",token
))in
->error(in
,"not an event definition");
501 getRAnglebracket(in
); //</event>
504 case NAME
: /* a field */
505 if(strcmp("field",token
))in
->error(in
,"expecting a field");
506 f
= (field_t
*)memAlloc(sizeof(field_t
));
507 sequence_push(&(ev
->fields
),f
);
508 parseFields(in
, f
, unnamed_types
, named_types
, 1);
511 in
->error(in
, "expecting </event> or <field >");
516 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
518 }else if(in
->type
== NAME
){
519 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
521 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
522 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
523 in
->error(in
,"type must be a struct");
524 }else in
->error(in
, "not a valid type");
526 getLAnglebracket(in
);
528 }else in
->error(in
,"not a struct type");
529 getLAnglebracket(in
);
532 if(strcmp("event",token
))in
->error(in
,"not an event definition");
533 getRAnglebracket(in
); //</event>
537 /*****************************************************************************
539 * parseField : get field infomation from buffer
541 * in : input file handle
543 * unnamed_types : array of unamed types
544 * named_types : array of named types
545 * tag : is field surrounded by a <field> </field> tag ?
546 ****************************************************************************/
548 void parseFields(parse_file_t
*in
, field_t
*f
,
549 sequence_t
* unnamed_types
,
550 table_t
* named_types
,
555 //<field name=field_name> <description> <type> </field>
556 getFieldAttributes(in
, f
);
557 if(f
->name
== NULL
) in
->error(in
, "Field not named");
558 getRAnglebracket(in
);
560 f
->description
= getDescription(in
);
562 f
->description
= NULL
;
566 getLAnglebracket(in
);
567 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
570 getLAnglebracket(in
);
573 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
574 getRAnglebracket(in
); //</field>
579 /*****************************************************************************
581 * parseType : get type information, type can be :
583 * int(size,fmt); uint(size,fmt); float(size,fmt);
584 * string(fmt); enum(size,fmt,(label1,label2...))
586 * array(arraySize, type); sequence(lengthSize,type)
587 * struct(field(name,type,description)...)
591 * in : input file handle
592 * inType : a type descriptor
593 * unnamed_types : array of unamed types
594 * named_types : array of named types
596 * type_descriptor* : a type descriptor
597 ****************************************************************************/
599 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
600 sequence_t
* unnamed_types
, table_t
* named_types
)
603 type_descriptor_t
*t
;
607 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
611 sequence_push(unnamed_types
,t
);
617 if(strcmp(token
,"struct") == 0) {
619 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
620 getRAnglebracket(in
); //<struct>
621 getLAnglebracket(in
); //<field name=..>
622 token
= getToken(in
);
623 sequence_init(&(t
->fields
));
624 while(strcmp("field",token
) == 0){
625 f
= (field_t
*)memAlloc(sizeof(field_t
));
626 sequence_push(&(t
->fields
),f
);
628 parseFields(in
, f
, unnamed_types
, named_types
, 1);
631 getLAnglebracket(in
);
632 token
= getToken(in
);
634 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
636 if(strcmp("struct",token
)!=0)
637 in
->error(in
,"not a valid structure definition");
638 getRAnglebracket(in
); //</struct>
640 else if(strcmp(token
,"union") == 0) {
642 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
643 getRAnglebracket(in
); //<union>
645 getLAnglebracket(in
); //<field name=..>
646 token
= getToken(in
);
647 sequence_init(&(t
->fields
));
648 while(strcmp("field",token
) == 0){
649 f
= (field_t
*)memAlloc(sizeof(field_t
));
650 sequence_push(&(t
->fields
),f
);
651 parseFields(in
, f
, unnamed_types
, named_types
, 1);
654 getLAnglebracket(in
);
655 token
= getToken(in
);
657 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
659 if(strcmp("union",token
)!=0)
660 in
->error(in
,"not a valid union definition");
661 getRAnglebracket(in
); //</union>
663 else if(strcmp(token
,"array") == 0) {
665 sequence_init(&(t
->fields
));
666 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
667 if(t
->size
== 0) in
->error(in
, "Array has empty size");
669 getRAnglebracket(in
); //<array size=n>
671 //getLAnglebracket(in); //<subtype>
673 f
= (field_t
*)memAlloc(sizeof(field_t
));
674 sequence_push(&(t
->fields
),f
);
675 parseFields(in
, f
, unnamed_types
, named_types
, 0);
677 //getLAnglebracket(in); //<type struct>
678 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
680 getLAnglebracket(in
); //</array>
683 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
684 getRAnglebracket(in
); //</array>
686 else if(strcmp(token
,"sequence") == 0) {
688 sequence_init(&(t
->fields
));
689 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
691 getRAnglebracket(in
); //<sequence>
693 //getLAnglebracket(in); //<sequence size type>
695 f
= (field_t
*)memAlloc(sizeof(field_t
));
696 sequence_push(&(t
->fields
),f
);
697 parseFields(in
, f
, unnamed_types
, named_types
, 0);
699 //getLAnglebracket(in); //<subtype>
701 f
= (field_t
*)memAlloc(sizeof(field_t
));
702 sequence_push(&(t
->fields
),f
);
703 parseFields(in
, f
, unnamed_types
, named_types
, 0);
705 //getLAnglebracket(in); //<type sequence>
706 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
708 //getLAnglebracket(in); //<type sequence>
710 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
712 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
713 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
714 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
724 in
->error(in
, "Wrong length type for sequence");
727 getLAnglebracket(in
); //</sequence>
730 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
731 getRAnglebracket(in
); //</sequence>
733 else if(strcmp(token
,"enum") == 0) {
738 sequence_init(&(t
->labels
));
739 sequence_init(&(t
->labels_values
));
740 sequence_init(&(t
->labels_description
));
741 t
->already_printed
= 0;
742 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
743 //if(t->size == 0) in->error(in, "Sequence has empty size");
744 //Mathieu : we fix enum size to target int size. GCC is always like this.
745 //fox copy optimisation.
746 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
748 getRAnglebracket(in
);
750 //<label name=label1 value=n/>
751 getLAnglebracket(in
);
752 token
= getToken(in
); //"label" or "/"
753 while(strcmp("label",token
) == 0){
754 int *label_value
= malloc(sizeof(int));
756 str
= allocAndCopy(getNameAttribute(in
));
757 token
= getValueStrAttribute(in
);
759 sequence_push(&(t
->labels
),str
);
761 if(token
) value
= strtol(token
, NULL
, 0);
764 *label_value
= value
;
765 sequence_push(&(t
->labels_values
), label_value
);
768 getRAnglebracket(in
);
770 //read description if any. May be NULL.
771 str
= allocAndCopy(getDescription(in
));
772 sequence_push(&(t
->labels_description
),str
);
774 //next label definition
775 getLAnglebracket(in
);
776 token
= getToken(in
); //"label" or "/"
778 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
780 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
781 getRAnglebracket(in
); //</label>
783 else if(strcmp(token
,"int_fixed") == 0) {
785 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
786 if(t
->size
== 0) in
->error(in
, "int has empty size");
788 getRAnglebracket(in
);
790 else if(strcmp(token
,"uint_fixed") == 0) {
791 t
->type
= UINT_FIXED
;
792 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
793 if(t
->size
== 0) in
->error(in
, "uint has empty size");
795 getRAnglebracket(in
);
797 else if(strcmp(token
,"char") == 0) {
799 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
802 getRAnglebracket(in
);
804 else if(strcmp(token
,"uchar") == 0) {
806 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
809 getRAnglebracket(in
);
811 else if(strcmp(token
,"short") == 0) {
813 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
816 getRAnglebracket(in
);
818 else if(strcmp(token
,"ushort") == 0) {
820 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
823 getRAnglebracket(in
);
825 else if(strcmp(token
,"int") == 0) {
827 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
829 getRAnglebracket(in
);
831 else if(strcmp(token
,"uint") == 0) {
833 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
835 getRAnglebracket(in
);
838 else if(strcmp(token
,"pointer") == 0) {
840 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
842 getRAnglebracket(in
);
844 else if(strcmp(token
,"long") == 0) {
846 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
848 getRAnglebracket(in
);
850 else if(strcmp(token
,"ulong") == 0) {
852 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
854 getRAnglebracket(in
);
856 else if(strcmp(token
,"size_t") == 0) {
858 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
860 getRAnglebracket(in
);
862 else if(strcmp(token
,"ssize_t") == 0) {
864 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
866 getRAnglebracket(in
);
868 else if(strcmp(token
,"off_t") == 0) {
870 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
872 getRAnglebracket(in
);
874 else if(strcmp(token
,"float") == 0) {
876 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
878 getRAnglebracket(in
);
880 else if(strcmp(token
,"string") == 0) {
882 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
884 getRAnglebracket(in
);
886 else if(strcmp(token
,"typeref") == 0){
887 // Must be a named type
889 sequence_pop(unnamed_types
);
890 token
= getNameAttribute(in
);
891 t
= find_named_type(token
, named_types
);
892 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
893 getForwardslash(in
); //<typeref name=type_name/>
894 getRAnglebracket(in
);
896 }else in
->error(in
,"not a valid type");
901 /*****************************************************************************
903 * find_named_type : find a named type from hash table
906 * named_types : array of named types
908 * type_descriptor * : a type descriptor
909 *****************************************************************************/
911 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
913 type_descriptor_t
*t
;
915 t
= table_find(named_types
,name
);
920 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
922 type_descriptor_t
*t
;
924 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
925 t
->type_name
= allocAndCopy(name
);
928 table_insert(named_types
,t
->type_name
,t
);
929 // table_insert(named_types,allocAndCopy(name),t);
933 /*****************************************************************************
935 * parseTypeDefinition : get type information from type definition
937 * in : input file handle
938 * unnamed_types : array of unamed types
939 * named_types : array of named types
940 *****************************************************************************/
942 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
943 table_t
* named_types
)
946 type_descriptor_t
*t
;
948 token
= getNameAttribute(in
);
949 if(token
== NULL
) in
->error(in
, "Type has empty name");
950 t
= create_named_type(token
, named_types
);
952 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
953 getRAnglebracket(in
); //<type name=type_name>
954 getLAnglebracket(in
); //<
956 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
958 parseType(in
,t
, unnamed_types
, named_types
);
961 getLAnglebracket(in
);
964 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
965 getRAnglebracket(in
); //</type>
968 /**************************************************************************
970 * getComa, getName, getNumber, getEqual
972 * Read a token from the input file, check its type, return it scontent.
975 * in , input file handle.
978 * address of token content.
980 **************************************************************************/
982 char *getName(parse_file_t
* in
)
986 token
= getToken(in
);
987 // Optional descriptions
988 // if(in->type != NAME) in->error(in,"Name token was expected");
992 int getNumber(parse_file_t
* in
)
996 token
= getToken(in
);
997 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
1001 char *getForwardslash(parse_file_t
* in
)
1005 token
= getToken(in
);
1006 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1007 /* Mathieu : final / is optional now. */
1008 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1013 char *getLAnglebracket(parse_file_t
* in
)
1017 token
= getToken(in
);
1018 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1022 char *getRAnglebracket(parse_file_t
* in
)
1026 token
= getToken(in
);
1027 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1031 char *getQuotedString(parse_file_t
* in
)
1035 token
= getToken(in
);
1036 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1040 char * getEqual(parse_file_t
*in
)
1044 token
= getToken(in
);
1045 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1049 char seekNextChar(parse_file_t
*in
)
1052 while((car
= getc(in
->fp
)) != EOF
) {
1061 /******************************************************************
1063 * getToken, ungetToken
1065 * Read a token from the input file and return its type and content.
1066 * Line numbers are accounted for and whitespace/comments are skipped.
1069 * in, input file handle.
1072 * address of token content.
1074 ******************************************************************/
1076 void ungetToken(parse_file_t
* in
)
1081 char *getToken(parse_file_t
* in
)
1085 int pos
= 0, escaped
;
1087 if(in
->unget
== 1) {
1092 /* skip whitespace and comments */
1094 while((car
= getc(fp
)) != EOF
) {
1097 if(car1
== '*') skipComment(in
);
1098 else if(car1
== '/') skipEOL(in
);
1100 car1
= ungetc(car1
,fp
);
1104 else if(car
== '\n') in
->lineno
++;
1105 else if(!isspace(car
)) break;
1113 in
->type
= FORWARDSLASH
;
1114 in
->buffer
[pos
] = car
;
1118 in
->type
= LANGLEBRACKET
;
1119 in
->buffer
[pos
] = car
;
1123 in
->type
= RANGLEBRACKET
;
1124 in
->buffer
[pos
] = car
;
1129 in
->buffer
[pos
] = car
;
1134 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1135 if(car
== '\\' && escaped
== 0) {
1136 in
->buffer
[pos
] = car
;
1141 if(car
== '"' && escaped
== 0) break;
1142 if(car
== '\n' && escaped
== 0) {
1143 in
->error(in
, "non escaped newline inside quoted string");
1145 if(car
== '\n') in
->lineno
++;
1146 in
->buffer
[pos
] = car
;
1150 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1151 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1152 in
->type
= QUOTEDSTRING
;
1156 in
->buffer
[pos
] = car
;
1158 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1163 in
->buffer
[pos
] = car
;
1166 if(car
== EOF
) ungetc(car
,fp
);
1167 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1170 else if(isalnum(car
) || car
== '_' || car
== '-') {
1171 in
->buffer
[0] = car
;
1173 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1174 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1178 in
->buffer
[pos
] = car
;
1181 if(car
== EOF
) ungetc(car
,fp
);
1182 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1185 else in
->error(in
, "invalid character, unrecognized token");
1187 in
->buffer
[pos
] = 0;
1191 void skipComment(parse_file_t
* in
)
1194 while((car
= getc(in
->fp
)) != EOF
) {
1195 if(car
== '\n') in
->lineno
++;
1196 else if(car
== '*') {
1198 if(car
==EOF
) break;
1199 if(car
== '/') return;
1203 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1206 void skipEOL(parse_file_t
* in
)
1209 while((car
= getc(in
->fp
)) != EOF
) {
1215 if(car
== EOF
)ungetc(car
, in
->fp
);
1218 /*****************************************************************************
1220 * checkNamedTypesImplemented : check if all named types have definition
1221 ****************************************************************************/
1223 void checkNamedTypesImplemented(table_t
* named_types
)
1225 type_descriptor_t
*t
;
1229 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1230 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1231 if(t
->type
== NONE
){
1232 sprintf(str
,"named type '%s' has no definition",
1233 (char*)named_types
->keys
.array
[pos
]);
1234 error_callback(NULL
,str
);
1240 /*****************************************************************************
1242 * generateChecksum : generate checksum for the facility
1244 * facName : name of facility
1246 * checksum : checksum for the facility
1247 ****************************************************************************/
1249 void generateChecksum(char* facName
,
1250 unsigned int * checksum
, sequence_t
* events
)
1257 crc
= crc32(facName
);
1258 for(pos
= 0; pos
< events
->position
; pos
++){
1259 ev
= (event_t
*)(events
->array
[pos
]);
1260 crc
= partial_crc32(ev
->name
, crc
);
1261 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1262 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1263 crc
= partial_crc32(f
->name
, crc
);
1264 crc
= getTypeChecksum(crc
, f
->type
);
1270 /*****************************************************************************
1272 * getTypeChecksum : generate checksum by type info
1274 * crc : checksum generated so far
1275 * type : type descriptor containing type info
1277 * unsigned long : checksum
1278 *****************************************************************************/
1280 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1282 unsigned long crc
= aCrc
;
1283 char * str
= NULL
, buf
[16];
1289 str
= intOutputTypes
[getSizeindex(type
->size
)];
1292 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1295 str
= allocAndCopy("void *");
1299 str
= allocAndCopy("signed char");
1303 str
= allocAndCopy("unsigned char");
1307 str
= allocAndCopy("short");
1311 str
= allocAndCopy("unsigned short");
1315 str
= allocAndCopy("int");
1319 str
= allocAndCopy("uint");
1323 str
= allocAndCopy("long");
1327 str
= allocAndCopy("unsigned long");
1331 str
= allocAndCopy("size_t");
1335 str
= allocAndCopy("ssize_t");
1339 str
= allocAndCopy("off_t");
1343 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1346 str
= allocAndCopy("string");
1350 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1351 str
= allocAndCopy("enum");
1355 sprintf(buf
,"%zu", type
->size
);
1356 str
= appendString("array ",buf
);
1360 str
= allocAndCopy("sequence ");
1364 str
= allocAndCopy("struct");
1368 str
= allocAndCopy("union");
1372 error_callback(NULL
, "named type has no definition");
1376 crc
= partial_crc32(str
,crc
);
1379 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1381 if(type
->type
== ARRAY
){
1382 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1383 } else if(type
->type
==SEQUENCE
) {
1384 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1385 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1386 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1387 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1388 fld
= (field_t
*) type
->fields
.array
[pos
];
1389 crc
= partial_crc32(fld
->name
,crc
);
1390 crc
= getTypeChecksum(crc
, fld
->type
);
1392 }else if(type
->type
== ENUM
){
1393 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1394 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1401 /* Event type descriptors */
1402 void freeType(type_descriptor_t
* tp
)
1407 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1408 if(tp
->type
== ENUM
) {
1409 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1410 free(tp
->labels
.array
[pos2
]);
1412 sequence_dispose(&(tp
->labels
));
1413 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1414 free(tp
->labels_values
.array
[pos2
]);
1416 sequence_dispose(&(tp
->labels_values
));
1418 if(tp
->type
== STRUCT
) {
1419 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1420 f
= (field_t
*) tp
->fields
.array
[pos2
];
1422 free(f
->description
);
1425 sequence_dispose(&(tp
->fields
));
1429 void freeNamedType(table_t
* t
)
1432 type_descriptor_t
* td
;
1434 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1435 free((char *)t
->keys
.array
[pos
]);
1436 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1442 void freeTypes(sequence_t
*t
)
1445 type_descriptor_t
*tp
;
1447 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1448 tp
= (type_descriptor_t
*)t
->array
[pos
];
1454 void freeEvents(sequence_t
*t
)
1459 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1460 ev
= (event_t
*) t
->array
[pos
];
1462 free(ev
->description
);
1463 sequence_dispose(&ev
->fields
);
1470 /* Extensible array */
1472 void sequence_init(sequence_t
*t
)
1476 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1479 void sequence_dispose(sequence_t
*t
)
1486 void sequence_push(sequence_t
*t
, void *elem
)
1490 if(t
->position
>= t
->size
) {
1492 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1493 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1494 t
->size
= t
->size
* 2;
1497 t
->array
[t
->position
] = elem
;
1501 void *sequence_pop(sequence_t
*t
)
1503 if(t
->position
== 0) printf("Error : trying to pop an empty sequence");
1504 return t
->array
[--t
->position
];
1508 /* Hash table API, implementation is just linear search for now */
1510 void table_init(table_t
*t
)
1512 sequence_init(&(t
->keys
));
1513 sequence_init(&(t
->values
));
1516 void table_dispose(table_t
*t
)
1518 sequence_dispose(&(t
->keys
));
1519 sequence_dispose(&(t
->values
));
1522 void table_insert(table_t
*t
, char *key
, void *value
)
1524 sequence_push(&(t
->keys
),key
);
1525 sequence_push(&(t
->values
),value
);
1528 void *table_find(table_t
*t
, char *key
)
1531 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1532 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1533 return(t
->values
.array
[pos
]);
1538 void table_insert_int(table_t
*t
, int *key
, void *value
)
1540 sequence_push(&(t
->keys
),key
);
1541 sequence_push(&(t
->values
),value
);
1544 void *table_find_int(table_t
*t
, int *key
)
1547 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1548 if(*key
== *(int *)t
->keys
.array
[pos
])
1549 return(t
->values
.array
[pos
]);
1555 /* Concatenate strings */
1557 char *appendString(char *s
, char *suffix
)
1560 if(suffix
== NULL
) return s
;
1562 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.107593 seconds and 5 git commands to generate.