d998c81381b17672b4bf0caf8de0fd45d03abaa7
3 parser.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* This program reads the ".xml" event definitions input files
23 and constructs structure for each event.
25 The program uses a very simple tokenizer, called from a hand written
26 recursive descent parser to fill a data structure describing the events.
27 The result is a sequence of events definitions which refer to type
30 A table of named types is maintained to allow refering to types by name
31 when the same type is used at several places. Finally a sequence of
32 all types is maintained to facilitate the freeing of all type
33 information when the processing of an ".xml" file is finished. */
39 #include <linux/errno.h>
46 void strupper(char *string
)
57 int getSizeindex(int value
)
69 printf("Error : unknown value size %d\n", value
);
74 /*****************************************************************************
76 * getSize : translate from string to integer
78 * in : input file handle
81 *****************************************************************************/
83 int getSize(parse_file
*in
)
88 if(in
->type
== NUMBER
) {
89 if(strcmp(token
,"1") == 0) return 0;
90 else if(strcmp(token
,"2") == 0) return 1;
91 else if(strcmp(token
,"4") == 0) return 2;
92 else if(strcmp(token
,"8") == 0) return 3;
94 else if(in
->type
== NAME
) {
95 if(strcmp(token
,"short") == 0) return 4;
96 else if(strcmp(token
,"medium") == 0) return 5;
97 else if(strcmp(token
,"long") == 0) return 6;
99 in
->error(in
,"incorrect size specification");
103 /*****************************************************************************
105 * error_callback : print out error info
107 * in : input file handle
108 * msg : message to be printed
109 ****************************************************************************/
111 void error_callback(parse_file
*in
, char *msg
)
114 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
120 /*****************************************************************************
122 * memAlloc : allocate memory
124 * size : required memory size
126 * void * : pointer to allocate memory or NULL
127 ****************************************************************************/
129 void * memAlloc(int size
)
132 if(size
== 0) return NULL
;
135 printf("Failed to allocate memory");
141 /*****************************************************************************
143 * allocAndCopy : allocate memory and initialize it
145 * str : string to be put in memory
147 * char * : pointer to allocate memory or NULL
148 ****************************************************************************/
150 char *allocAndCopy(char *str
)
153 if(str
== NULL
) return NULL
;
154 addr
= (char *)memAlloc(strlen(str
)+1);
159 /**************************************************************************
161 * getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute
162 * getValueStrAttribute
164 * Read the attribute from the input file.
167 * in , input file handle.
170 * address of the attribute.
172 **************************************************************************/
174 char * getNameAttribute(parse_file
*in
)
178 if(strcmp("name",token
))in
->error(in
,"name was expected");
181 car
= seekNextChar(in
);
182 if(car
== EOF
)in
->error(in
,"name was expected");
183 else if(car
== '\"')token
= getQuotedString(in
);
184 else token
= getName(in
);
188 char * getFormatAttribute(parse_file
*in
)
192 //format is an option
193 token
= getToken(in
);
194 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
199 if(strcmp("format",token
))in
->error(in
,"format was expected");
201 token
= getQuotedString(in
);
205 int getSizeAttribute(parse_file
*in
)
214 int getValueAttribute(parse_file
*in
)
220 return getNumber(in
);
223 //for <label name=label_name value=n/>, value is an option
224 char * getValueStrAttribute(parse_file
*in
)
228 token
= getToken(in
);
229 if(strcmp("/",token
) == 0){
234 if(strcmp("value",token
))in
->error(in
,"value was expected");
236 token
= getToken(in
);
237 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
241 char * getDescription(parse_file
*in
)
244 char * token
, car
, *str
;
248 getLAnglebracket(in
);
250 if(strcmp("description",token
)){
251 fseek(in
->fp
, pos
, SEEK_SET
);
255 getRAnglebracket(in
);
258 while((car
= getc(in
->fp
)) != EOF
) {
259 if(car
== '<') break;
260 if(car
== '\0') continue;
261 in
->buffer
[pos
] = car
;
264 if(car
== EOF
)in
->error(in
,"not a valid description");
265 in
->buffer
[pos
] = '\0';
267 str
= allocAndCopy(in
->buffer
);
271 if(strcmp("description", token
))in
->error(in
,"not a valid description");
272 getRAnglebracket(in
);
277 /*****************************************************************************
279 * parseFacility : generate event list
281 * in : input file handle
282 * fac : empty facility
284 * fac : facility filled with event list
285 ****************************************************************************/
287 void parseFacility(parse_file
*in
, facility
* fac
)
292 fac
->name
= allocAndCopy(getNameAttribute(in
));
293 fac
->capname
= allocAndCopy(fac
->name
);
294 strupper(fac
->capname
);
295 getRAnglebracket(in
);
297 fac
->description
= getDescription(in
);
300 getLAnglebracket(in
);
302 token
= getToken(in
);
303 if(in
->type
== ENDFILE
)
304 in
->error(in
,"the definition of the facility is not finished");
306 if(strcmp("event",token
) == 0){
307 ev
= (event
*) memAlloc(sizeof(event
));
308 sequence_push(&(fac
->events
),ev
);
309 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
310 }else if(strcmp("type",token
) == 0){
311 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
312 }else if(in
->type
== FORWARDSLASH
){
314 }else in
->error(in
,"event or type token expected\n");
318 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
319 getRAnglebracket(in
); //</facility>
322 /*****************************************************************************
324 * parseEvent : generate event from event definition
326 * in : input file handle
328 * unnamed_types : array of unamed types
329 * named_types : array of named types
331 * ev : new event (parameters are passed to it)
332 ****************************************************************************/
334 void parseEvent(parse_file
*in
, event
* ev
, sequence
* unnamed_types
,
340 //<event name=eventtype_name>
341 ev
->name
= allocAndCopy(getNameAttribute(in
));
342 getRAnglebracket(in
);
344 //<description>...</descriptio>
345 ev
->description
= getDescription(in
);
347 //event can have STRUCT, TYPEREF or NOTHING
348 getLAnglebracket(in
);
350 token
= getToken(in
);
351 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
353 }else if(in
->type
== NAME
){
354 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
356 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
357 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
358 in
->error(in
,"type must be a struct");
359 }else in
->error(in
, "not a valid type");
361 getLAnglebracket(in
);
363 }else in
->error(in
,"not a struct type");
366 if(strcmp("event",token
))in
->error(in
,"not an event definition");
367 getRAnglebracket(in
); //</event>
370 /*****************************************************************************
372 * parseField : get field infomation from buffer
374 * in : input file handle
375 * t : type descriptor
376 * unnamed_types : array of unamed types
377 * named_types : array of named types
378 ****************************************************************************/
380 void parseFields(parse_file
*in
, type_descriptor
*t
, sequence
* unnamed_types
,
386 f
= (field
*)memAlloc(sizeof(field
));
387 sequence_push(&(t
->fields
),f
);
389 //<field name=field_name> <description> <type> </field>
390 f
->name
= allocAndCopy(getNameAttribute(in
));
391 getRAnglebracket(in
);
393 f
->description
= getDescription(in
);
396 getLAnglebracket(in
);
397 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
399 getLAnglebracket(in
);
402 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
403 getRAnglebracket(in
); //</field>
407 /*****************************************************************************
409 * parseType : get type information, type can be :
411 * int(size,fmt); uint(size,fmt); float(size,fmt);
412 * string(fmt); enum(size,fmt,(label1,label2...))
414 * array(arraySize, type); sequence(lengthSize,type)
415 * struct(field(name,type,description)...)
419 * in : input file handle
420 * inType : a type descriptor
421 * unnamed_types : array of unamed types
422 * named_types : array of named types
424 * type_descriptor* : a type descriptor
425 ****************************************************************************/
427 type_descriptor
*parseType(parse_file
*in
, type_descriptor
*inType
,
428 sequence
* unnamed_types
, table
* named_types
)
434 t
= (type_descriptor
*) memAlloc(sizeof(type_descriptor
));
438 sequence_push(unnamed_types
,t
);
444 if(strcmp(token
,"struct") == 0) {
446 getRAnglebracket(in
); //<struct>
447 getLAnglebracket(in
); //<field name=..>
448 token
= getToken(in
);
449 sequence_init(&(t
->fields
));
450 while(strcmp("field",token
) == 0){
451 parseFields(in
,t
, unnamed_types
, named_types
);
454 getLAnglebracket(in
);
455 token
= getToken(in
);
457 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
459 if(strcmp("struct",token
)!=0)
460 in
->error(in
,"not a valid structure definition");
461 getRAnglebracket(in
); //</struct>
463 else if(strcmp(token
,"union") == 0) {
465 t
->size
= getSizeAttribute(in
);
466 getRAnglebracket(in
); //<union typecodesize=isize>
468 getLAnglebracket(in
); //<field name=..>
469 token
= getToken(in
);
470 sequence_init(&(t
->fields
));
471 while(strcmp("field",token
) == 0){
472 parseFields(in
,t
, unnamed_types
, named_types
);
475 getLAnglebracket(in
);
476 token
= getToken(in
);
478 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
480 if(strcmp("union",token
)!=0)
481 in
->error(in
,"not a valid union definition");
482 getRAnglebracket(in
); //</union>
484 else if(strcmp(token
,"array") == 0) {
486 t
->size
= getValueAttribute(in
);
487 getRAnglebracket(in
); //<array size=n>
489 getLAnglebracket(in
); //<type struct>
490 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
492 getLAnglebracket(in
); //</array>
495 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
496 getRAnglebracket(in
); //</array>
498 else if(strcmp(token
,"sequence") == 0) {
500 t
->size
= getSizeAttribute(in
);
501 getRAnglebracket(in
); //<array lengthsize=isize>
503 getLAnglebracket(in
); //<type struct>
504 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
506 getLAnglebracket(in
); //</sequence>
509 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
510 getRAnglebracket(in
); //</sequence>
512 else if(strcmp(token
,"enum") == 0) {
515 sequence_init(&(t
->labels
));
516 sequence_init(&(t
->labels_description
));
517 t
->already_printed
= 0;
518 t
->size
= getSizeAttribute(in
);
519 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
520 getRAnglebracket(in
);
522 //<label name=label1 value=n/>
523 getLAnglebracket(in
);
524 token
= getToken(in
); //"label" or "/"
525 while(strcmp("label",token
) == 0){
526 str
= allocAndCopy(getNameAttribute(in
));
527 token
= getValueStrAttribute(in
);
529 str1
= appendString(str
,"=");
531 str
= appendString(str1
,token
);
533 sequence_push(&(t
->labels
),str
);
536 sequence_push(&(t
->labels
),str
);
539 getRAnglebracket(in
);
541 //read description if any. May be NULL.
542 str
= allocAndCopy(getDescription(in
));
543 sequence_push(&(t
->labels_description
),str
);
545 //next label definition
546 getLAnglebracket(in
);
547 token
= getToken(in
); //"label" or "/"
549 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
551 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
552 getRAnglebracket(in
); //</label>
554 else if(strcmp(token
,"int") == 0) {
556 t
->size
= getSizeAttribute(in
);
557 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
559 getRAnglebracket(in
);
561 else if(strcmp(token
,"uint") == 0) {
563 t
->size
= getSizeAttribute(in
);
564 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
566 getRAnglebracket(in
);
568 else if(strcmp(token
,"pointer") == 0) {
571 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
573 getRAnglebracket(in
);
575 else if(strcmp(token
,"long") == 0) {
578 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
580 getRAnglebracket(in
);
582 else if(strcmp(token
,"ulong") == 0) {
585 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
587 getRAnglebracket(in
);
589 else if(strcmp(token
,"size_t") == 0) {
592 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
594 getRAnglebracket(in
);
596 else if(strcmp(token
,"ssize_t") == 0) {
599 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
601 getRAnglebracket(in
);
603 else if(strcmp(token
,"off_t") == 0) {
606 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
608 getRAnglebracket(in
);
610 else if(strcmp(token
,"float") == 0) {
612 t
->size
= getSizeAttribute(in
);
613 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
615 getRAnglebracket(in
);
617 else if(strcmp(token
,"string") == 0) {
619 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
621 getRAnglebracket(in
);
623 else if(strcmp(token
,"typeref") == 0){
624 // Must be a named type
626 in
->error(in
,"Named type cannot refer to a named type");
629 sequence_pop(unnamed_types
);
630 token
= getNameAttribute(in
);
631 t
= find_named_type(token
, named_types
);
632 getForwardslash(in
); //<typeref name=type_name/>
633 getRAnglebracket(in
);
636 }else in
->error(in
,"not a valid type");
641 /*****************************************************************************
643 * find_named_type : find a named type from hash table
646 * named_types : array of named types
648 * type_descriptor * : a type descriptor
649 *****************************************************************************/
651 type_descriptor
* find_named_type(char *name
, table
* named_types
)
655 t
= table_find(named_types
,name
);
657 t
= (type_descriptor
*)memAlloc(sizeof(type_descriptor
));
658 t
->type_name
= allocAndCopy(name
);
661 table_insert(named_types
,t
->type_name
,t
);
662 // table_insert(named_types,allocAndCopy(name),t);
667 /*****************************************************************************
669 * parseTypeDefinition : get type information from type definition
671 * in : input file handle
672 * unnamed_types : array of unamed types
673 * named_types : array of named types
674 *****************************************************************************/
676 void parseTypeDefinition(parse_file
* in
, sequence
* unnamed_types
,
682 token
= getNameAttribute(in
);
683 t
= find_named_type(token
, named_types
);
685 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
686 getRAnglebracket(in
); //<type name=type_name>
687 getLAnglebracket(in
); //<struct>
689 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
691 parseType(in
,t
, unnamed_types
, named_types
);
694 getLAnglebracket(in
);
697 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
698 getRAnglebracket(in
); //</type>
701 /**************************************************************************
703 * getComa, getName, getNumber, getEqual
705 * Read a token from the input file, check its type, return it scontent.
708 * in , input file handle.
711 * address of token content.
713 **************************************************************************/
715 char *getName(parse_file
* in
)
719 token
= getToken(in
);
720 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
724 int getNumber(parse_file
* in
)
728 token
= getToken(in
);
729 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
733 char *getForwardslash(parse_file
* in
)
737 token
= getToken(in
);
738 if(in
->type
!= FORWARDSLASH
) in
->error(in
, "forward slash token was expected");
742 char *getLAnglebracket(parse_file
* in
)
746 token
= getToken(in
);
747 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
751 char *getRAnglebracket(parse_file
* in
)
755 token
= getToken(in
);
756 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
760 char *getQuotedString(parse_file
* in
)
764 token
= getToken(in
);
765 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
769 char * getEqual(parse_file
*in
)
773 token
= getToken(in
);
774 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
778 char seekNextChar(parse_file
*in
)
781 while((car
= getc(in
->fp
)) != EOF
) {
790 /******************************************************************
792 * getToken, ungetToken
794 * Read a token from the input file and return its type and content.
795 * Line numbers are accounted for and whitespace/comments are skipped.
798 * in, input file handle.
801 * address of token content.
803 ******************************************************************/
805 void ungetToken(parse_file
* in
)
810 char *getToken(parse_file
* in
)
814 int pos
= 0, escaped
;
821 /* skip whitespace and comments */
823 while((car
= getc(fp
)) != EOF
) {
826 if(car1
== '*') skipComment(in
);
827 else if(car1
== '/') skipEOL(in
);
829 car1
= ungetc(car1
,fp
);
833 else if(car
== '\n') in
->lineno
++;
834 else if(!isspace(car
)) break;
842 in
->type
= FORWARDSLASH
;
843 in
->buffer
[pos
] = car
;
847 in
->type
= LANGLEBRACKET
;
848 in
->buffer
[pos
] = car
;
852 in
->type
= RANGLEBRACKET
;
853 in
->buffer
[pos
] = car
;
858 in
->buffer
[pos
] = car
;
863 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
864 if(car
== '\\' && escaped
== 0) {
865 in
->buffer
[pos
] = car
;
870 if(car
== '"' && escaped
== 0) break;
871 if(car
== '\n' && escaped
== 0) {
872 in
->error(in
, "non escaped newline inside quoted string");
874 if(car
== '\n') in
->lineno
++;
875 in
->buffer
[pos
] = car
;
879 if(car
== EOF
) in
->error(in
,"no ending quotemark");
880 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
881 in
->type
= QUOTEDSTRING
;
885 in
->buffer
[pos
] = car
;
887 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
892 in
->buffer
[pos
] = car
;
895 if(car
== EOF
) ungetc(car
,fp
);
896 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
899 else if(isalpha(car
)) {
902 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
903 if(!(isalnum(car
) || car
== '_')) {
907 in
->buffer
[pos
] = car
;
910 if(car
== EOF
) ungetc(car
,fp
);
911 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
914 else in
->error(in
, "invalid character, unrecognized token");
920 void skipComment(parse_file
* in
)
923 while((car
= getc(in
->fp
)) != EOF
) {
924 if(car
== '\n') in
->lineno
++;
925 else if(car
== '*') {
928 if(car
== '/') return;
932 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
935 void skipEOL(parse_file
* in
)
938 while((car
= getc(in
->fp
)) != EOF
) {
944 if(car
== EOF
)ungetc(car
, in
->fp
);
947 /*****************************************************************************
949 * checkNamedTypesImplemented : check if all named types have definition
950 ****************************************************************************/
952 void checkNamedTypesImplemented(table
* named_types
)
958 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
959 t
= (type_descriptor
*) named_types
->values
.array
[pos
];
961 sprintf(str
,"named type '%s' has no definition",(char*)named_types
->keys
.array
[pos
]);
962 error_callback(NULL
,str
);
968 /*****************************************************************************
970 * generateChecksum : generate checksum for the facility
972 * facName : name of facility
974 * checksum : checksum for the facility
975 ****************************************************************************/
977 void generateChecksum( char* facName
, unsigned long * checksum
, sequence
* events
)
984 crc
= crc32(facName
);
985 for(pos
= 0; pos
< events
->position
; pos
++){
986 ev
= (event
*)(events
->array
[pos
]);
987 crc
= partial_crc32(ev
->name
,crc
);
988 if(!ev
->type
) continue; //event without type
989 if(ev
->type
->type
!= STRUCT
){
990 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
991 error_callback(NULL
, str
);
993 crc
= getTypeChecksum(crc
, ev
->type
);
998 /*****************************************************************************
1000 * getTypeChecksum : generate checksum by type info
1002 * crc : checksum generated so far
1003 * type : type descriptor containing type info
1005 * unsigned long : checksum
1006 *****************************************************************************/
1008 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor
* type
)
1010 unsigned long crc
= aCrc
;
1011 char * str
= NULL
, buf
[16];
1017 str
= intOutputTypes
[type
->size
];
1020 str
= uintOutputTypes
[type
->size
];
1023 str
= allocAndCopy("void *");
1027 str
= allocAndCopy("long");
1031 str
= allocAndCopy("unsigned long");
1035 str
= allocAndCopy("size_t");
1039 str
= allocAndCopy("ssize_t");
1043 str
= allocAndCopy("off_t");
1047 str
= floatOutputTypes
[type
->size
];
1050 str
= allocAndCopy("string");
1054 str
= appendString("enum ", uintOutputTypes
[type
->size
]);
1058 sprintf(buf
,"%d\0",type
->size
);
1059 str
= appendString("array ",buf
);
1063 sprintf(buf
,"%d\0",type
->size
);
1064 str
= appendString("sequence ",buf
);
1068 str
= allocAndCopy("struct");
1072 str
= allocAndCopy("union");
1076 error_callback(NULL
, "named type has no definition");
1080 crc
= partial_crc32(str
,crc
);
1083 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1085 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1086 crc
= getTypeChecksum(crc
,type
->nested_type
);
1087 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1088 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1089 fld
= (field
*) type
->fields
.array
[pos
];
1090 crc
= partial_crc32(fld
->name
,crc
);
1091 crc
= getTypeChecksum(crc
, fld
->type
);
1093 }else if(type
->type
== ENUM
){
1094 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1095 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1102 /* Event type descriptors */
1103 void freeType(type_descriptor
* tp
)
1108 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1109 if(tp
->type
== ENUM
) {
1110 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1111 free(tp
->labels
.array
[pos2
]);
1113 sequence_dispose(&(tp
->labels
));
1115 if(tp
->type
== STRUCT
) {
1116 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1117 f
= (field
*) tp
->fields
.array
[pos2
];
1119 free(f
->description
);
1122 sequence_dispose(&(tp
->fields
));
1126 void freeNamedType(table
* t
)
1129 type_descriptor
* td
;
1131 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1132 free((char *)t
->keys
.array
[pos
]);
1133 td
= (type_descriptor
*)t
->values
.array
[pos
];
1139 void freeTypes(sequence
*t
)
1142 type_descriptor
*tp
;
1145 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1146 tp
= (type_descriptor
*)t
->array
[pos
];
1152 void freeEvents(sequence
*t
)
1157 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1158 ev
= (event
*) t
->array
[pos
];
1160 free(ev
->description
);
1167 /* Extensible array */
1169 void sequence_init(sequence
*t
)
1173 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1176 void sequence_dispose(sequence
*t
)
1183 void sequence_push(sequence
*t
, void *elem
)
1187 if(t
->position
>= t
->size
) {
1189 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1190 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1191 t
->size
= t
->size
* 2;
1194 t
->array
[t
->position
] = elem
;
1198 void *sequence_pop(sequence
*t
)
1200 return t
->array
[t
->position
--];
1204 /* Hash table API, implementation is just linear search for now */
1206 void table_init(table
*t
)
1208 sequence_init(&(t
->keys
));
1209 sequence_init(&(t
->values
));
1212 void table_dispose(table
*t
)
1214 sequence_dispose(&(t
->keys
));
1215 sequence_dispose(&(t
->values
));
1218 void table_insert(table
*t
, char *key
, void *value
)
1220 sequence_push(&(t
->keys
),key
);
1221 sequence_push(&(t
->values
),value
);
1224 void *table_find(table
*t
, char *key
)
1227 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1228 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1229 return(t
->values
.array
[pos
]);
1234 void table_insert_int(table
*t
, int *key
, void *value
)
1236 sequence_push(&(t
->keys
),key
);
1237 sequence_push(&(t
->values
),value
);
1240 void *table_find_int(table
*t
, int *key
)
1243 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1244 if(*key
== *(int *)t
->keys
.array
[pos
])
1245 return(t
->values
.array
[pos
]);
1251 /* Concatenate strings */
1253 char *appendString(char *s
, char *suffix
)
1256 if(suffix
== NULL
) return s
;
1258 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.056402 seconds and 3 git commands to generate.