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 unsigned long long int ret
;
103 token
= getToken(in
);
104 if(token
[0] == '"') {
106 token
= getToken(in
);
108 if(in
->type
== NUMBER
) {
109 ret
= strtoull(token
, NULL
, 0);
114 token
= getToken(in
);
115 if(token
[0] != '"') goto error
;
120 in
->error(in
,"incorrect size specification");
124 /*****************************************************************************
126 * error_callback : print out error info
128 * in : input file handle
129 * msg : message to be printed
130 ****************************************************************************/
132 void error_callback(parse_file_t
*in
, char *msg
)
135 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
142 /*****************************************************************************
144 * memAlloc : allocate memory
146 * size : required memory size
148 * void * : pointer to allocate memory or NULL
149 ****************************************************************************/
151 void * memAlloc(int size
)
154 if(size
== 0) return NULL
;
157 printf("Failed to allocate memory");
163 /*****************************************************************************
165 * allocAndCopy : allocate memory and initialize it
167 * str : string to be put in memory
169 * char * : pointer to allocate memory or NULL
170 ****************************************************************************/
172 char *allocAndCopy(char *str
)
175 if(str
== NULL
) return NULL
;
176 addr
= (char *)memAlloc(strlen(str
)+1);
181 /**************************************************************************
185 * Read the attribute from the input file.
188 * in , input file handle.
189 * t , the type descriptor to fill.
191 **************************************************************************/
193 void getTypeAttributes(parse_file_t
*in
, type_descriptor_t
*t
,
194 sequence_t
* unnamed_types
, table_t
* named_types
)
204 token
= getToken(in
);
205 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
210 if(!strcmp("format",token
)) {
212 t
->fmt
= allocAndCopy(getQuotedString(in
));
213 //} else if(!strcmp("name",token)) {
215 // car = seekNextChar(in);
216 // if(car == EOF) in->error(in,"name was expected");
217 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
218 // else t->type_name = allocAndCopy(getName(in));
219 } else if(!strcmp("size",token
)) {
221 t
->size
= getSize(in
);
222 } else if(!strcmp("custom_write", token
)) {
224 } else if(!strcmp("network", token
)) {
230 /**************************************************************************
234 * Read the attribute from the input file.
237 * in , input file handle.
238 * ev , the event to fill.
240 **************************************************************************/
242 void getEventAttributes(parse_file_t
*in
, event_t
*ev
)
249 ev
->per_tracefile
= 0;
250 ev
->param_buffer
= 0;
253 token
= getToken(in
);
254 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
259 if(!strcmp("name",token
)) {
261 car
= seekNextChar(in
);
262 if(car
== EOF
) in
->error(in
,"name was expected");
263 else if(car
== '\"') ev
->name
= allocAndCopy(getQuotedString(in
));
264 else ev
->name
= allocAndCopy(getName(in
));
265 } else if(!strcmp("per_trace", token
)) {
267 } else if(!strcmp("per_tracefile", token
)) {
268 ev
->per_tracefile
= 1;
269 } else if(!strcmp("param_buffer", token
)) {
270 ev
->param_buffer
= 1;
276 /**************************************************************************
278 * getFacilityAttributes
280 * Read the attribute from the input file.
283 * in , input file handle.
284 * fac , the facility to fill.
286 **************************************************************************/
288 void getFacilityAttributes(parse_file_t
*in
, facility_t
*fac
)
298 token
= getToken(in
);
299 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
304 if(!strcmp("name",token
)) {
306 car
= seekNextChar(in
);
307 if(car
== EOF
) in
->error(in
,"name was expected");
308 else if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
309 else fac
->name
= allocAndCopy(getName(in
));
310 if(!strncmp(fac
->name
, "user_", sizeof("user_")) == 0)
312 } else if(!strcmp("arch", token
)) {
314 car
= seekNextChar(in
);
315 if(car
== '\"') fac
->name
= allocAndCopy(getQuotedString(in
));
316 else fac
->arch
= allocAndCopy(getName(in
));
321 /**************************************************************************
325 * Read the attribute from the input file.
328 * in , input file handle.
329 * f , the field to fill.
331 **************************************************************************/
333 void getFieldAttributes(parse_file_t
*in
, field_t
*f
)
341 token
= getToken(in
);
342 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
347 if(!strcmp("name",token
)) {
349 car
= seekNextChar(in
);
350 if(car
== EOF
) in
->error(in
,"name was expected");
351 else if(car
== '\"') f
->name
= allocAndCopy(getQuotedString(in
));
352 else f
->name
= allocAndCopy(getName(in
));
357 char *getNameAttribute(parse_file_t
*in
)
364 token
= getToken(in
);
365 if(!strcmp("name",token
)) {
367 car
= seekNextChar(in
);
368 if(car
== EOF
) in
->error(in
,"name was expected");
369 else if(car
== '\"') name
= allocAndCopy(getQuotedString(in
));
370 else name
= allocAndCopy(getName(in
));
377 if(name
== NULL
) in
->error(in
, "Name was expected");
383 //for <label name=label_name value=n format="..."/>, value is an option
384 //Return value : 0 : no value, 1 : has a value
385 int getValueAttribute(parse_file_t
*in
, long long *value
)
390 token
= getToken(in
);
391 if(strcmp("/",token
) == 0){
396 if(strcmp("value",token
))in
->error(in
,"value was expected");
398 token
= getToken(in
);
400 if(token
[0] == '"') {
402 token
= getToken(in
);
404 if(in
->type
== NUMBER
) {
405 *value
= strtoll(token
, NULL
, 0);
410 token
= getToken(in
);
411 if(token
[0] != '"') goto error
;
416 in
->error(in
,"incorrect size specification");
420 char * getDescription(parse_file_t
*in
)
423 char * token
, car
, *str
;
427 getLAnglebracket(in
);
429 if(strcmp("description",token
)){
430 fseek(in
->fp
, pos
, SEEK_SET
);
434 getRAnglebracket(in
);
437 while((car
= getc(in
->fp
)) != EOF
) {
438 if(car
== '<') break;
439 if(car
== '\0') continue;
440 in
->buffer
[pos
] = car
;
443 if(car
== EOF
)in
->error(in
,"not a valid description");
444 in
->buffer
[pos
] = '\0';
446 str
= allocAndCopy(in
->buffer
);
450 if(strcmp("description", token
))in
->error(in
,"not a valid description");
451 getRAnglebracket(in
);
456 /*****************************************************************************
458 * parseFacility : generate event list
460 * in : input file handle
461 * fac : empty facility
463 * fac : facility filled with event list
464 ****************************************************************************/
466 void parseFacility(parse_file_t
*in
, facility_t
* fac
)
471 getFacilityAttributes(in
, fac
);
472 if(fac
->name
== NULL
) in
->error(in
, "Attribute not named");
474 fac
->capname
= allocAndCopy(fac
->name
);
475 strupper(fac
->capname
);
476 getRAnglebracket(in
);
478 fac
->description
= getDescription(in
);
481 getLAnglebracket(in
);
483 token
= getToken(in
);
484 if(in
->type
== ENDFILE
)
485 in
->error(in
,"the definition of the facility is not finished");
487 if(strcmp("event",token
) == 0){
488 ev
= (event_t
*) memAlloc(sizeof(event_t
));
489 sequence_push(&(fac
->events
),ev
);
490 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
491 }else if(strcmp("type",token
) == 0){
492 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
493 }else if(in
->type
== FORWARDSLASH
){
495 }else in
->error(in
,"event or type token expected\n");
499 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
500 getRAnglebracket(in
); //</facility>
503 /*****************************************************************************
505 * parseEvent : generate event from event definition
507 * in : input file handle
509 * unnamed_types : array of unamed types
510 * named_types : array of named types
512 * ev : new event (parameters are passed to it)
513 ****************************************************************************/
515 void parseEvent(parse_file_t
*in
, event_t
* ev
, sequence_t
* unnamed_types
,
516 table_t
* named_types
)
521 sequence_init(&(ev
->fields
));
522 //<event name=eventtype_name>
523 getEventAttributes(in
, ev
);
524 if(ev
->name
== NULL
) in
->error(in
, "Event not named");
525 getRAnglebracket(in
);
527 //<description>...</description>
528 ev
->description
= getDescription(in
);
531 /* Events can have multiple fields. each field form at least a function
532 * parameter of the logging function. */
534 getLAnglebracket(in
);
535 token
= getToken(in
);
538 case FORWARDSLASH
: /* </event> */
540 if(strcmp("event",token
))in
->error(in
,"not an event definition");
541 getRAnglebracket(in
); //</event>
544 case NAME
: /* a field */
545 if(strcmp("field",token
))in
->error(in
,"expecting a field");
546 f
= (field_t
*)memAlloc(sizeof(field_t
));
547 sequence_push(&(ev
->fields
),f
);
548 parseFields(in
, f
, unnamed_types
, named_types
, 1);
551 in
->error(in
, "expecting </event> or <field >");
556 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
558 }else if(in
->type
== NAME
){
559 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
561 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
562 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
563 in
->error(in
,"type must be a struct");
564 }else in
->error(in
, "not a valid type");
566 getLAnglebracket(in
);
568 }else in
->error(in
,"not a struct type");
569 getLAnglebracket(in
);
572 if(strcmp("event",token
))in
->error(in
,"not an event definition");
573 getRAnglebracket(in
); //</event>
577 /*****************************************************************************
579 * parseField : get field infomation from buffer
581 * in : input file handle
583 * unnamed_types : array of unamed types
584 * named_types : array of named types
585 * tag : is field surrounded by a <field> </field> tag ?
586 ****************************************************************************/
588 void parseFields(parse_file_t
*in
, field_t
*f
,
589 sequence_t
* unnamed_types
,
590 table_t
* named_types
,
595 //<field name=field_name> <description> <type> </field>
596 getFieldAttributes(in
, f
);
597 if(f
->name
== NULL
) in
->error(in
, "Field not named");
598 getRAnglebracket(in
);
600 f
->description
= getDescription(in
);
602 f
->description
= NULL
;
606 getLAnglebracket(in
);
607 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
610 getLAnglebracket(in
);
613 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
614 getRAnglebracket(in
); //</field>
619 /*****************************************************************************
621 * parseType : get type information, type can be :
623 * int(size,fmt); uint(size,fmt); float(size,fmt);
624 * string(fmt); enum(size,fmt,(label1,label2...))
626 * array(arraySize, type); sequence(lengthSize,type)
627 * struct(field(name,type,description)...)
631 * in : input file handle
632 * inType : a type descriptor
633 * unnamed_types : array of unamed types
634 * named_types : array of named types
636 * type_descriptor* : a type descriptor
637 ****************************************************************************/
639 type_descriptor_t
*parseType(parse_file_t
*in
, type_descriptor_t
*inType
,
640 sequence_t
* unnamed_types
, table_t
* named_types
)
643 type_descriptor_t
*t
;
647 t
= (type_descriptor_t
*) memAlloc(sizeof(type_descriptor_t
));
651 sequence_push(unnamed_types
,t
);
657 if(strcmp(token
,"struct") == 0) {
659 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
660 getRAnglebracket(in
); //<struct>
661 getLAnglebracket(in
); //<field name=..>
662 token
= getToken(in
);
663 sequence_init(&(t
->fields
));
664 while(strcmp("field",token
) == 0){
665 f
= (field_t
*)memAlloc(sizeof(field_t
));
666 sequence_push(&(t
->fields
),f
);
668 parseFields(in
, f
, unnamed_types
, named_types
, 1);
671 getLAnglebracket(in
);
672 token
= getToken(in
);
674 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
676 if(strcmp("struct",token
)!=0)
677 in
->error(in
,"not a valid structure definition");
678 getRAnglebracket(in
); //</struct>
680 else if(strcmp(token
,"union") == 0) {
682 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
683 getRAnglebracket(in
); //<union>
685 getLAnglebracket(in
); //<field name=..>
686 token
= getToken(in
);
687 sequence_init(&(t
->fields
));
688 while(strcmp("field",token
) == 0){
689 f
= (field_t
*)memAlloc(sizeof(field_t
));
690 sequence_push(&(t
->fields
),f
);
691 parseFields(in
, f
, unnamed_types
, named_types
, 1);
694 getLAnglebracket(in
);
695 token
= getToken(in
);
697 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
699 if(strcmp("union",token
)!=0)
700 in
->error(in
,"not a valid union definition");
701 getRAnglebracket(in
); //</union>
703 else if(strcmp(token
,"array") == 0) {
705 sequence_init(&(t
->fields
));
706 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
707 if(t
->size
== 0) in
->error(in
, "Array has empty size");
709 getRAnglebracket(in
); //<array size=n>
711 //getLAnglebracket(in); //<subtype>
713 f
= (field_t
*)memAlloc(sizeof(field_t
));
714 sequence_push(&(t
->fields
),f
);
715 parseFields(in
, f
, unnamed_types
, named_types
, 0);
717 //getLAnglebracket(in); //<type struct>
718 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
720 getLAnglebracket(in
); //</array>
723 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
724 getRAnglebracket(in
); //</array>
726 else if(strcmp(token
,"sequence") == 0) {
728 sequence_init(&(t
->fields
));
729 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
731 getRAnglebracket(in
); //<sequence>
733 //getLAnglebracket(in); //<sequence size type>
735 f
= (field_t
*)memAlloc(sizeof(field_t
));
736 sequence_push(&(t
->fields
),f
);
737 parseFields(in
, f
, unnamed_types
, named_types
, 0);
739 //getLAnglebracket(in); //<subtype>
741 f
= (field_t
*)memAlloc(sizeof(field_t
));
742 sequence_push(&(t
->fields
),f
);
743 parseFields(in
, f
, unnamed_types
, named_types
, 0);
745 //getLAnglebracket(in); //<type sequence>
746 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
748 //getLAnglebracket(in); //<type sequence>
750 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
752 if(t
->fields
.position
< 1) in
->error(in
, "Sequence has no length type");
753 if(t
->fields
.position
< 2) in
->error(in
, "Sequence has no subtype");
754 switch(((field_t
*)t
->fields
.array
[0])->type
->type
) {
764 in
->error(in
, "Wrong length type for sequence");
767 getLAnglebracket(in
); //</sequence>
770 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
771 getRAnglebracket(in
); //</sequence>
773 else if(strcmp(token
,"enum") == 0) {
775 long long value
= -1;
778 sequence_init(&(t
->labels
));
779 sequence_init(&(t
->labels_values
));
780 sequence_init(&(t
->labels_description
));
781 t
->already_printed
= 0;
782 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
783 //if(t->size == 0) in->error(in, "Sequence has empty size");
784 //Mathieu : we fix enum size to target int size. GCC is always like this.
785 //fox copy optimisation.
786 if(t
->size
!= 0) in
->error(in
, "Enum has fixed size of target int.");
788 getRAnglebracket(in
);
790 //<label name=label1 value=n/>
791 getLAnglebracket(in
);
792 token
= getToken(in
); //"label" or "/"
793 while(strcmp("label",token
) == 0){
794 int *label_value
= malloc(sizeof(int));
798 str
= allocAndCopy(getNameAttribute(in
));
799 has_value
= getValueAttribute(in
, &loc_value
);
801 sequence_push(&(t
->labels
),str
);
803 if(has_value
) value
= loc_value
;
806 *label_value
= value
;
807 sequence_push(&(t
->labels_values
), label_value
);
810 getRAnglebracket(in
);
812 //read description if any. May be NULL.
813 str
= allocAndCopy(getDescription(in
));
814 sequence_push(&(t
->labels_description
),str
);
816 //next label definition
817 getLAnglebracket(in
);
818 token
= getToken(in
); //"label" or "/"
820 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
822 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
823 getRAnglebracket(in
); //</label>
825 else if(strcmp(token
,"int_fixed") == 0) {
827 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
828 if(t
->size
== 0) in
->error(in
, "int has empty size");
830 getRAnglebracket(in
);
832 else if(strcmp(token
,"uint_fixed") == 0) {
833 t
->type
= UINT_FIXED
;
834 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
835 if(t
->size
== 0) in
->error(in
, "uint has empty size");
837 getRAnglebracket(in
);
839 else if(strcmp(token
,"char") == 0) {
841 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
844 getRAnglebracket(in
);
846 else if(strcmp(token
,"uchar") == 0) {
848 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
851 getRAnglebracket(in
);
853 else if(strcmp(token
,"short") == 0) {
855 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
858 getRAnglebracket(in
);
860 else if(strcmp(token
,"ushort") == 0) {
862 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
865 getRAnglebracket(in
);
867 else if(strcmp(token
,"int") == 0) {
869 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
871 getRAnglebracket(in
);
873 else if(strcmp(token
,"uint") == 0) {
875 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
877 getRAnglebracket(in
);
880 else if(strcmp(token
,"pointer") == 0) {
882 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
884 getRAnglebracket(in
);
886 else if(strcmp(token
,"long") == 0) {
888 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
890 getRAnglebracket(in
);
892 else if(strcmp(token
,"ulong") == 0) {
894 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
896 getRAnglebracket(in
);
898 else if(strcmp(token
,"size_t") == 0) {
900 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
902 getRAnglebracket(in
);
904 else if(strcmp(token
,"ssize_t") == 0) {
906 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
908 getRAnglebracket(in
);
910 else if(strcmp(token
,"off_t") == 0) {
912 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
914 getRAnglebracket(in
);
916 else if(strcmp(token
,"float") == 0) {
918 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
920 getRAnglebracket(in
);
922 else if(strcmp(token
,"string") == 0) {
924 getTypeAttributes(in
, t
, unnamed_types
, named_types
);
926 getRAnglebracket(in
);
928 else if(strcmp(token
,"typeref") == 0){
929 // Must be a named type
931 sequence_pop(unnamed_types
);
932 token
= getNameAttribute(in
);
933 t
= find_named_type(token
, named_types
);
934 if(t
== NULL
) in
->error(in
,"Named referred to must be pre-declared.");
935 getForwardslash(in
); //<typeref name=type_name/>
936 getRAnglebracket(in
);
938 }else in
->error(in
,"not a valid type");
943 /*****************************************************************************
945 * find_named_type : find a named type from hash table
948 * named_types : array of named types
950 * type_descriptor * : a type descriptor
951 *****************************************************************************/
953 type_descriptor_t
* find_named_type(char *name
, table_t
* named_types
)
955 type_descriptor_t
*t
;
957 t
= table_find(named_types
,name
);
962 type_descriptor_t
* create_named_type(char *name
, table_t
* named_types
)
964 type_descriptor_t
*t
;
966 t
= (type_descriptor_t
*)memAlloc(sizeof(type_descriptor_t
));
967 t
->type_name
= allocAndCopy(name
);
970 table_insert(named_types
,t
->type_name
,t
);
971 // table_insert(named_types,allocAndCopy(name),t);
975 /*****************************************************************************
977 * parseTypeDefinition : get type information from type definition
979 * in : input file handle
980 * unnamed_types : array of unamed types
981 * named_types : array of named types
982 *****************************************************************************/
984 void parseTypeDefinition(parse_file_t
* in
, sequence_t
* unnamed_types
,
985 table_t
* named_types
)
988 type_descriptor_t
*t
;
990 token
= getNameAttribute(in
);
991 if(token
== NULL
) in
->error(in
, "Type has empty name");
992 t
= create_named_type(token
, named_types
);
994 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
995 getRAnglebracket(in
); //<type name=type_name>
996 getLAnglebracket(in
); //<
998 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
1000 parseType(in
,t
, unnamed_types
, named_types
);
1003 getLAnglebracket(in
);
1004 getForwardslash(in
);
1005 token
= getName(in
);
1006 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
1007 getRAnglebracket(in
); //</type>
1010 /**************************************************************************
1012 * getComa, getName, getNumber, getEqual
1014 * Read a token from the input file, check its type, return it scontent.
1017 * in , input file handle.
1020 * address of token content.
1022 **************************************************************************/
1024 char *getName(parse_file_t
* in
)
1028 token
= getToken(in
);
1029 // Optional descriptions
1030 // if(in->type != NAME) in->error(in,"Name token was expected");
1034 int getNumber(parse_file_t
* in
)
1038 token
= getToken(in
);
1039 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
1043 char *getForwardslash(parse_file_t
* in
)
1047 token
= getToken(in
);
1048 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1049 /* Mathieu : final / is optional now. */
1050 if(in
->type
!= FORWARDSLASH
) ungetToken(in
);
1055 char *getLAnglebracket(parse_file_t
* in
)
1059 token
= getToken(in
);
1060 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
1064 char *getRAnglebracket(parse_file_t
* in
)
1068 token
= getToken(in
);
1069 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
1073 char *getQuotedString(parse_file_t
* in
)
1077 token
= getToken(in
);
1078 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
1082 char * getEqual(parse_file_t
*in
)
1086 token
= getToken(in
);
1087 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
1091 char seekNextChar(parse_file_t
*in
)
1094 while((car
= getc(in
->fp
)) != EOF
) {
1103 /******************************************************************
1105 * getToken, ungetToken
1107 * Read a token from the input file and return its type and content.
1108 * Line numbers are accounted for and whitespace/comments are skipped.
1111 * in, input file handle.
1114 * address of token content.
1116 ******************************************************************/
1118 void ungetToken(parse_file_t
* in
)
1123 char *getToken(parse_file_t
* in
)
1127 int pos
= 0, escaped
;
1129 if(in
->unget
== 1) {
1134 /* skip whitespace and comments */
1136 while((car
= getc(fp
)) != EOF
) {
1139 if(car1
== '*') skipComment(in
);
1140 else if(car1
== '/') skipEOL(in
);
1142 car1
= ungetc(car1
,fp
);
1146 else if(car
== '\n') in
->lineno
++;
1147 else if(!isspace(car
)) break;
1155 in
->type
= FORWARDSLASH
;
1156 in
->buffer
[pos
] = car
;
1160 in
->type
= LANGLEBRACKET
;
1161 in
->buffer
[pos
] = car
;
1165 in
->type
= RANGLEBRACKET
;
1166 in
->buffer
[pos
] = car
;
1171 in
->buffer
[pos
] = car
;
1176 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1177 if(car
== '\\' && escaped
== 0) {
1178 in
->buffer
[pos
] = car
;
1183 if(car
== '"' && escaped
== 0) break;
1184 if(car
== '\n' && escaped
== 0) {
1185 in
->error(in
, "non escaped newline inside quoted string");
1187 if(car
== '\n') in
->lineno
++;
1188 in
->buffer
[pos
] = car
;
1192 if(car
== EOF
) in
->error(in
,"no ending quotemark");
1193 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
1194 in
->type
= QUOTEDSTRING
;
1198 in
->buffer
[pos
] = car
;
1200 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1205 in
->buffer
[pos
] = car
;
1208 if(car
== EOF
) ungetc(car
,fp
);
1209 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
1212 else if(isalnum(car
) || car
== '_' || car
== '-') {
1213 in
->buffer
[0] = car
;
1215 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
1216 if(!(isalnum(car
) || car
== '_' || car
== '-')) {
1220 in
->buffer
[pos
] = car
;
1223 if(car
== EOF
) ungetc(car
,fp
);
1224 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
1227 else in
->error(in
, "invalid character, unrecognized token");
1229 in
->buffer
[pos
] = 0;
1233 void skipComment(parse_file_t
* in
)
1236 while((car
= getc(in
->fp
)) != EOF
) {
1237 if(car
== '\n') in
->lineno
++;
1238 else if(car
== '*') {
1240 if(car
==EOF
) break;
1241 if(car
== '/') return;
1245 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
1248 void skipEOL(parse_file_t
* in
)
1251 while((car
= getc(in
->fp
)) != EOF
) {
1257 if(car
== EOF
)ungetc(car
, in
->fp
);
1260 /*****************************************************************************
1262 * checkNamedTypesImplemented : check if all named types have definition
1263 ****************************************************************************/
1265 void checkNamedTypesImplemented(table_t
* named_types
)
1267 type_descriptor_t
*t
;
1271 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
1272 t
= (type_descriptor_t
*) named_types
->values
.array
[pos
];
1273 if(t
->type
== NONE
){
1274 sprintf(str
,"named type '%s' has no definition",
1275 (char*)named_types
->keys
.array
[pos
]);
1276 error_callback(NULL
,str
);
1282 /*****************************************************************************
1284 * generateChecksum : generate checksum for the facility
1286 * facName : name of facility
1288 * checksum : checksum for the facility
1289 ****************************************************************************/
1291 void generateChecksum(char* facName
,
1292 unsigned int * checksum
, sequence_t
* events
)
1299 crc
= crc32(facName
);
1300 for(pos
= 0; pos
< events
->position
; pos
++){
1301 ev
= (event_t
*)(events
->array
[pos
]);
1302 crc
= partial_crc32(ev
->name
, crc
);
1303 for(i
= 0; i
< ev
->fields
.position
; i
++) {
1304 field_t
*f
= (field_t
*)ev
->fields
.array
[i
];
1305 crc
= partial_crc32(f
->name
, crc
);
1306 crc
= getTypeChecksum(crc
, f
->type
);
1312 /*****************************************************************************
1314 * getTypeChecksum : generate checksum by type info
1316 * crc : checksum generated so far
1317 * type : type descriptor containing type info
1319 * unsigned long : checksum
1320 *****************************************************************************/
1322 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor_t
* type
)
1324 unsigned long crc
= aCrc
;
1325 char * str
= NULL
, buf
[16];
1331 str
= intOutputTypes
[getSizeindex(type
->size
)];
1334 str
= uintOutputTypes
[getSizeindex(type
->size
)];
1337 str
= allocAndCopy("void *");
1341 str
= allocAndCopy("signed char");
1345 str
= allocAndCopy("unsigned char");
1349 str
= allocAndCopy("short");
1353 str
= allocAndCopy("unsigned short");
1357 str
= allocAndCopy("int");
1361 str
= allocAndCopy("uint");
1365 str
= allocAndCopy("long");
1369 str
= allocAndCopy("unsigned long");
1373 str
= allocAndCopy("size_t");
1377 str
= allocAndCopy("ssize_t");
1381 str
= allocAndCopy("off_t");
1385 str
= floatOutputTypes
[getSizeindex(type
->size
)];
1388 str
= allocAndCopy("string");
1392 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1393 str
= allocAndCopy("enum");
1397 sprintf(buf
,"%zu", type
->size
);
1398 str
= appendString("array ",buf
);
1402 str
= allocAndCopy("sequence ");
1406 str
= allocAndCopy("struct");
1410 str
= allocAndCopy("union");
1414 error_callback(NULL
, "named type has no definition");
1418 crc
= partial_crc32(str
,crc
);
1421 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1423 if(type
->type
== ARRAY
){
1424 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1425 } else if(type
->type
==SEQUENCE
) {
1426 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[0])->type
);
1427 crc
= getTypeChecksum(crc
,((field_t
*)type
->fields
.array
[1])->type
);
1428 } else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1429 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1430 fld
= (field_t
*) type
->fields
.array
[pos
];
1431 crc
= partial_crc32(fld
->name
,crc
);
1432 crc
= getTypeChecksum(crc
, fld
->type
);
1434 }else if(type
->type
== ENUM
){
1435 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1436 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1443 /* Event type descriptors */
1444 void freeType(type_descriptor_t
* tp
)
1449 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1450 if(tp
->type
== ENUM
) {
1451 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1452 free(tp
->labels
.array
[pos2
]);
1454 sequence_dispose(&(tp
->labels
));
1455 for(pos2
= 0; pos2
< tp
->labels_values
.position
; pos2
++) {
1456 free(tp
->labels_values
.array
[pos2
]);
1458 sequence_dispose(&(tp
->labels_values
));
1460 if(tp
->type
== STRUCT
) {
1461 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1462 f
= (field_t
*) tp
->fields
.array
[pos2
];
1464 free(f
->description
);
1467 sequence_dispose(&(tp
->fields
));
1471 void freeNamedType(table_t
* t
)
1474 type_descriptor_t
* td
;
1476 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1477 free((char *)t
->keys
.array
[pos
]);
1478 td
= (type_descriptor_t
*)t
->values
.array
[pos
];
1484 void freeTypes(sequence_t
*t
)
1487 type_descriptor_t
*tp
;
1489 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1490 tp
= (type_descriptor_t
*)t
->array
[pos
];
1496 void freeEvents(sequence_t
*t
)
1501 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1502 ev
= (event_t
*) t
->array
[pos
];
1504 free(ev
->description
);
1505 sequence_dispose(&ev
->fields
);
1512 /* Extensible array */
1514 void sequence_init(sequence_t
*t
)
1518 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1521 void sequence_dispose(sequence_t
*t
)
1528 void sequence_push(sequence_t
*t
, void *elem
)
1532 if(t
->position
>= t
->size
) {
1534 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1535 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1536 t
->size
= t
->size
* 2;
1539 t
->array
[t
->position
] = elem
;
1543 void *sequence_pop(sequence_t
*t
)
1545 if(t
->position
== 0) printf("Error : trying to pop an empty sequence");
1546 return t
->array
[--t
->position
];
1550 /* Hash table API, implementation is just linear search for now */
1552 void table_init(table_t
*t
)
1554 sequence_init(&(t
->keys
));
1555 sequence_init(&(t
->values
));
1558 void table_dispose(table_t
*t
)
1560 sequence_dispose(&(t
->keys
));
1561 sequence_dispose(&(t
->values
));
1564 void table_insert(table_t
*t
, char *key
, void *value
)
1566 sequence_push(&(t
->keys
),key
);
1567 sequence_push(&(t
->values
),value
);
1570 void *table_find(table_t
*t
, char *key
)
1573 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1574 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1575 return(t
->values
.array
[pos
]);
1580 void table_insert_int(table_t
*t
, int *key
, void *value
)
1582 sequence_push(&(t
->keys
),key
);
1583 sequence_push(&(t
->values
),value
);
1586 void *table_find_int(table_t
*t
, int *key
)
1589 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1590 if(*key
== *(int *)t
->keys
.array
[pos
])
1591 return(t
->values
.array
[pos
]);
1597 /* Concatenate strings */
1599 char *appendString(char *s
, char *suffix
)
1602 if(suffix
== NULL
) return s
;
1604 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.064654 seconds and 4 git commands to generate.