fa786985316e015a880f4ad6c0db0153c23f16eb
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>
45 /*****************************************************************************
47 * getSize : translate from string to integer
49 * in : input file handle
52 *****************************************************************************/
54 int getSize(parse_file
*in
)
59 if(in
->type
== NUMBER
) {
60 if(strcmp(token
,"1") == 0) return 0;
61 else if(strcmp(token
,"2") == 0) return 1;
62 else if(strcmp(token
,"4") == 0) return 2;
63 else if(strcmp(token
,"8") == 0) return 3;
65 else if(in
->type
== NAME
) {
66 if(strcmp(token
,"short") == 0) return 4;
67 else if(strcmp(token
,"medium") == 0) return 5;
68 else if(strcmp(token
,"long") == 0) return 6;
70 in
->error(in
,"incorrect size specification");
74 /*****************************************************************************
76 * error_callback : print out error info
78 * in : input file handle
79 * msg : message to be printed
80 ****************************************************************************/
82 void error_callback(parse_file
*in
, char *msg
)
85 printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
91 /*****************************************************************************
93 * memAlloc : allocate memory
95 * size : required memory size
97 * void * : pointer to allocate memory or NULL
98 ****************************************************************************/
100 void * memAlloc(int size
)
103 if(size
== 0) return NULL
;
106 printf("Failed to allocate memory");
112 /*****************************************************************************
114 * allocAndCopy : allocate memory and initialize it
116 * str : string to be put in memory
118 * char * : pointer to allocate memory or NULL
119 ****************************************************************************/
121 char *allocAndCopy(char *str
)
124 if(str
== NULL
) return NULL
;
125 addr
= (char *)memAlloc(strlen(str
)+1);
130 /**************************************************************************
132 * getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute
133 * getValueStrAttribute
135 * Read the attribute from the input file.
138 * in , input file handle.
141 * address of the attribute.
143 **************************************************************************/
145 char * getNameAttribute(parse_file
*in
)
149 if(strcmp("name",token
))in
->error(in
,"name was expected");
152 car
= seekNextChar(in
);
153 if(car
== EOF
)in
->error(in
,"name was expected");
154 else if(car
== '\"')token
= getQuotedString(in
);
155 else token
= getName(in
);
159 char * getFormatAttribute(parse_file
*in
)
163 //format is an option
164 token
= getToken(in
);
165 if(strcmp("/",token
) == 0 || strcmp(">",token
) == 0){
170 if(strcmp("format",token
))in
->error(in
,"format was expected");
172 token
= getQuotedString(in
);
176 int getSizeAttribute(parse_file
*in
)
185 int getValueAttribute(parse_file
*in
)
191 return getNumber(in
);
194 //for <label name=label_name value=n/>, value is an option
195 char * getValueStrAttribute(parse_file
*in
)
199 token
= getToken(in
);
200 if(strcmp("/",token
) == 0){
205 if(strcmp("value",token
))in
->error(in
,"value was expected");
207 token
= getToken(in
);
208 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
212 char * getDescription(parse_file
*in
)
215 char * token
, car
, *str
;
219 getLAnglebracket(in
);
221 if(strcmp("description",token
)){
222 fseek(in
->fp
, pos
, SEEK_SET
);
226 getRAnglebracket(in
);
229 while((car
= getc(in
->fp
)) != EOF
) {
230 if(car
== '<') break;
231 if(car
== '\0') continue;
232 in
->buffer
[pos
] = car
;
235 if(car
== EOF
)in
->error(in
,"not a valid description");
236 in
->buffer
[pos
] = '\0';
238 str
= allocAndCopy(in
->buffer
);
242 if(strcmp("description", token
))in
->error(in
,"not a valid description");
243 getRAnglebracket(in
);
248 /*****************************************************************************
250 * parseFacility : generate event list
252 * in : input file handle
253 * fac : empty facility
255 * fac : facility filled with event list
256 ****************************************************************************/
258 void parseFacility(parse_file
*in
, facility
* fac
)
263 fac
->name
= allocAndCopy(getNameAttribute(in
));
264 getRAnglebracket(in
);
266 fac
->description
= getDescription(in
);
269 getLAnglebracket(in
);
271 token
= getToken(in
);
272 if(in
->type
== ENDFILE
)
273 in
->error(in
,"the definition of the facility is not finished");
275 if(strcmp("event",token
) == 0){
276 ev
= (event
*) memAlloc(sizeof(event
));
277 sequence_push(&(fac
->events
),ev
);
278 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
279 }else if(strcmp("type",token
) == 0){
280 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
281 }else if(in
->type
== FORWARDSLASH
){
283 }else in
->error(in
,"event or type token expected\n");
287 if(strcmp("facility",token
)) in
->error(in
,"not the end of the facility");
288 getRAnglebracket(in
); //</facility>
291 /*****************************************************************************
293 * parseEvent : generate event from event definition
295 * in : input file handle
297 * unnamed_types : array of unamed types
298 * named_types : array of named types
300 * ev : new event (parameters are passed to it)
301 ****************************************************************************/
303 void parseEvent(parse_file
*in
, event
* ev
, sequence
* unnamed_types
,
309 //<event name=eventtype_name>
310 ev
->name
= allocAndCopy(getNameAttribute(in
));
311 getRAnglebracket(in
);
313 //<description>...</descriptio>
314 ev
->description
= getDescription(in
);
316 //event can have STRUCT, TYPEREF or NOTHING
317 getLAnglebracket(in
);
319 token
= getToken(in
);
320 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
322 }else if(in
->type
== NAME
){
323 if(strcmp("struct",token
)==0 || strcmp("typeref",token
)==0){
325 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
326 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
327 in
->error(in
,"type must be a struct");
328 }else in
->error(in
, "not a valid type");
330 getLAnglebracket(in
);
332 }else in
->error(in
,"not a struct type");
335 if(strcmp("event",token
))in
->error(in
,"not an event definition");
336 getRAnglebracket(in
); //</event>
339 /*****************************************************************************
341 * parseField : get field infomation from buffer
343 * in : input file handle
344 * t : type descriptor
345 * unnamed_types : array of unamed types
346 * named_types : array of named types
347 ****************************************************************************/
349 void parseFields(parse_file
*in
, type_descriptor
*t
, sequence
* unnamed_types
,
355 f
= (field
*)memAlloc(sizeof(field
));
356 sequence_push(&(t
->fields
),f
);
358 //<field name=field_name> <description> <type> </field>
359 f
->name
= allocAndCopy(getNameAttribute(in
));
360 getRAnglebracket(in
);
362 f
->description
= getDescription(in
);
365 getLAnglebracket(in
);
366 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
368 getLAnglebracket(in
);
371 if(strcmp("field",token
))in
->error(in
,"not a valid field definition");
372 getRAnglebracket(in
); //</field>
376 /*****************************************************************************
378 * parseType : get type information, type can be :
380 * int(size,fmt); uint(size,fmt); float(size,fmt);
381 * string(fmt); enum(size,fmt,(label1,label2...))
383 * array(arraySize, type); sequence(lengthSize,type)
384 * struct(field(name,type,description)...)
388 * in : input file handle
389 * inType : a type descriptor
390 * unnamed_types : array of unamed types
391 * named_types : array of named types
393 * type_descriptor* : a type descriptor
394 ****************************************************************************/
396 type_descriptor
*parseType(parse_file
*in
, type_descriptor
*inType
,
397 sequence
* unnamed_types
, table
* named_types
)
403 t
= (type_descriptor
*) memAlloc(sizeof(type_descriptor
));
407 sequence_push(unnamed_types
,t
);
413 if(strcmp(token
,"struct") == 0) {
415 getRAnglebracket(in
); //<struct>
416 getLAnglebracket(in
); //<field name=..>
417 token
= getToken(in
);
418 sequence_init(&(t
->fields
));
419 while(strcmp("field",token
) == 0){
420 parseFields(in
,t
, unnamed_types
, named_types
);
423 getLAnglebracket(in
);
424 token
= getToken(in
);
426 if(strcmp("/",token
))in
->error(in
,"not a valid structure definition");
428 if(strcmp("struct",token
)!=0)
429 in
->error(in
,"not a valid structure definition");
430 getRAnglebracket(in
); //</struct>
432 else if(strcmp(token
,"union") == 0) {
434 t
->size
= getSizeAttribute(in
);
435 getRAnglebracket(in
); //<union typecodesize=isize>
437 getLAnglebracket(in
); //<field name=..>
438 token
= getToken(in
);
439 sequence_init(&(t
->fields
));
440 while(strcmp("field",token
) == 0){
441 parseFields(in
,t
, unnamed_types
, named_types
);
444 getLAnglebracket(in
);
445 token
= getToken(in
);
447 if(strcmp("/",token
))in
->error(in
,"not a valid union definition");
449 if(strcmp("union",token
)!=0)
450 in
->error(in
,"not a valid union definition");
451 getRAnglebracket(in
); //</union>
453 else if(strcmp(token
,"array") == 0) {
455 t
->size
= getValueAttribute(in
);
456 getRAnglebracket(in
); //<array size=n>
458 getLAnglebracket(in
); //<type struct>
459 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
461 getLAnglebracket(in
); //</array>
464 if(strcmp("array",token
))in
->error(in
,"not a valid array definition");
465 getRAnglebracket(in
); //</array>
467 else if(strcmp(token
,"sequence") == 0) {
469 t
->size
= getSizeAttribute(in
);
470 getRAnglebracket(in
); //<array lengthsize=isize>
472 getLAnglebracket(in
); //<type struct>
473 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
475 getLAnglebracket(in
); //</sequence>
478 if(strcmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
479 getRAnglebracket(in
); //</sequence>
481 else if(strcmp(token
,"enum") == 0) {
484 sequence_init(&(t
->labels
));
485 t
->size
= getSizeAttribute(in
);
486 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
487 getRAnglebracket(in
);
489 //<label name=label1 value=n/>
490 getLAnglebracket(in
);
491 token
= getToken(in
); //"label" or "/"
492 while(strcmp("label",token
) == 0){
493 str
= allocAndCopy(getNameAttribute(in
));
494 token
= getValueStrAttribute(in
);
496 str1
= appendString(str
,"=");
498 str
= appendString(str1
,token
);
500 sequence_push(&(t
->labels
),str
);
502 sequence_push(&(t
->labels
),str
);
505 getRAnglebracket(in
);
507 //next label definition
508 getLAnglebracket(in
);
509 token
= getToken(in
); //"label" or "/"
511 if(strcmp("/",token
))in
->error(in
, "not a valid enum definition");
513 if(strcmp("enum",token
))in
->error(in
, "not a valid enum definition");
514 getRAnglebracket(in
); //</label>
516 else if(strcmp(token
,"int") == 0) {
518 t
->size
= getSizeAttribute(in
);
519 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
521 getRAnglebracket(in
);
523 else if(strcmp(token
,"uint") == 0) {
525 t
->size
= getSizeAttribute(in
);
526 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
528 getRAnglebracket(in
);
530 else if(strcmp(token
,"float") == 0) {
532 t
->size
= getSizeAttribute(in
);
533 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
535 getRAnglebracket(in
);
537 else if(strcmp(token
,"string") == 0) {
539 t
->fmt
= allocAndCopy(getFormatAttribute(in
));
541 getRAnglebracket(in
);
543 else if(strcmp(token
,"typeref") == 0){
544 // Must be a named type
546 in
->error(in
,"Named type cannot refer to a named type");
549 sequence_pop(unnamed_types
);
550 token
= getNameAttribute(in
);
551 t
= find_named_type(token
, named_types
);
552 getForwardslash(in
); //<typeref name=type_name/>
553 getRAnglebracket(in
);
556 }else in
->error(in
,"not a valid type");
561 /*****************************************************************************
563 * find_named_type : find a named type from hash table
566 * named_types : array of named types
568 * type_descriptor * : a type descriptor
569 *****************************************************************************/
571 type_descriptor
* find_named_type(char *name
, table
* named_types
)
575 t
= table_find(named_types
,name
);
577 t
= (type_descriptor
*)memAlloc(sizeof(type_descriptor
));
578 t
->type_name
= allocAndCopy(name
);
581 table_insert(named_types
,allocAndCopy(name
),t
);
586 /*****************************************************************************
588 * parseTypeDefinition : get type information from type definition
590 * in : input file handle
591 * unnamed_types : array of unamed types
592 * named_types : array of named types
593 *****************************************************************************/
595 void parseTypeDefinition(parse_file
* in
, sequence
* unnamed_types
,
601 token
= getNameAttribute(in
);
602 t
= find_named_type(token
, named_types
);
604 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
605 getRAnglebracket(in
); //<type name=type_name>
606 getLAnglebracket(in
); //<struct>
608 if(strcmp("struct",token
))in
->error(in
,"not a valid type definition");
610 parseType(in
,t
, unnamed_types
, named_types
);
613 getLAnglebracket(in
);
616 if(strcmp("type",token
))in
->error(in
,"not a valid type definition");
617 getRAnglebracket(in
); //</type>
620 /**************************************************************************
622 * getComa, getName, getNumber, getEqual
624 * Read a token from the input file, check its type, return it scontent.
627 * in , input file handle.
630 * address of token content.
632 **************************************************************************/
634 char *getName(parse_file
* in
)
638 token
= getToken(in
);
639 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
643 int getNumber(parse_file
* in
)
647 token
= getToken(in
);
648 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
652 char *getForwardslash(parse_file
* in
)
656 token
= getToken(in
);
657 if(in
->type
!= FORWARDSLASH
) in
->error(in
, "forward slash token was expected");
661 char *getLAnglebracket(parse_file
* in
)
665 token
= getToken(in
);
666 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
670 char *getRAnglebracket(parse_file
* in
)
674 token
= getToken(in
);
675 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
679 char *getQuotedString(parse_file
* in
)
683 token
= getToken(in
);
684 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
688 char * getEqual(parse_file
*in
)
692 token
= getToken(in
);
693 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
697 char seekNextChar(parse_file
*in
)
700 while((car
= getc(in
->fp
)) != EOF
) {
709 /******************************************************************
711 * getToken, ungetToken
713 * Read a token from the input file and return its type and content.
714 * Line numbers are accounted for and whitespace/comments are skipped.
717 * in, input file handle.
720 * address of token content.
722 ******************************************************************/
724 void ungetToken(parse_file
* in
)
729 char *getToken(parse_file
* in
)
733 int pos
= 0, escaped
;
740 /* skip whitespace and comments */
742 while((car
= getc(fp
)) != EOF
) {
745 if(car1
== '*') skipComment(in
);
746 else if(car1
== '/') skipEOL(in
);
748 car1
= ungetc(car1
,fp
);
752 else if(car
== '\n') in
->lineno
++;
753 else if(!isspace(car
)) break;
761 in
->type
= FORWARDSLASH
;
762 in
->buffer
[pos
] = car
;
766 in
->type
= LANGLEBRACKET
;
767 in
->buffer
[pos
] = car
;
771 in
->type
= RANGLEBRACKET
;
772 in
->buffer
[pos
] = car
;
777 in
->buffer
[pos
] = car
;
782 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
783 if(car
== '\\' && escaped
== 0) {
784 in
->buffer
[pos
] = car
;
789 if(car
== '"' && escaped
== 0) break;
790 if(car
== '\n' && escaped
== 0) {
791 in
->error(in
, "non escaped newline inside quoted string");
793 if(car
== '\n') in
->lineno
++;
794 in
->buffer
[pos
] = car
;
798 if(car
== EOF
) in
->error(in
,"no ending quotemark");
799 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
800 in
->type
= QUOTEDSTRING
;
804 in
->buffer
[pos
] = car
;
806 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
811 in
->buffer
[pos
] = car
;
814 if(car
== EOF
) ungetc(car
,fp
);
815 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
818 else if(isalpha(car
)) {
821 while((car
= getc(fp
)) != EOF
&& pos
< BUFFER_SIZE
) {
826 in
->buffer
[pos
] = car
;
829 if(car
== EOF
) ungetc(car
,fp
);
830 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
833 else in
->error(in
, "invalid character, unrecognized token");
839 void skipComment(parse_file
* in
)
842 while((car
= getc(in
->fp
)) != EOF
) {
843 if(car
== '\n') in
->lineno
++;
844 else if(car
== '*') {
847 if(car
== '/') return;
851 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
854 void skipEOL(parse_file
* in
)
857 while((car
= getc(in
->fp
)) != EOF
) {
863 if(car
== EOF
)ungetc(car
, in
->fp
);
869 if(c
== '_')return 1;
872 if((i
>=0 && i
<26) || (j
>=0 && j
<26)) return 1;
878 return (isalpha(c
) || isdigit(c
));
881 /*****************************************************************************
883 * checkNamedTypesImplemented : check if all named types have definition
884 ****************************************************************************/
886 void checkNamedTypesImplemented(table
* named_types
)
892 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
893 t
= (type_descriptor
*) named_types
->values
.array
[pos
];
895 sprintf(str
,"named type '%s' has no definition",(char*)named_types
->keys
.array
[pos
]);
896 error_callback(NULL
,str
);
902 /*****************************************************************************
904 * generateChecksum : generate checksum for the facility
906 * facName : name of facility
908 * checksum : checksum for the facility
909 ****************************************************************************/
911 void generateChecksum( char* facName
, unsigned long * checksum
, sequence
* events
)
918 crc
= crc32(facName
);
919 for(pos
= 0; pos
< events
->position
; pos
++){
920 ev
= (event
*)(events
->array
[pos
]);
921 crc
= partial_crc32(ev
->name
,crc
);
922 if(!ev
->type
) continue; //event without type
923 if(ev
->type
->type
!= STRUCT
){
924 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
925 error_callback(NULL
, str
);
927 crc
= getTypeChecksum(crc
, ev
->type
);
932 /*****************************************************************************
934 * getTypeChecksum : generate checksum by type info
936 * crc : checksum generated so far
937 * type : type descriptor containing type info
939 * unsigned long : checksum
940 *****************************************************************************/
942 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor
* type
)
944 unsigned long crc
= aCrc
;
945 char * str
= NULL
, buf
[16];
951 str
= intOutputTypes
[type
->size
];
954 str
= uintOutputTypes
[type
->size
];
957 str
= floatOutputTypes
[type
->size
];
960 str
= allocAndCopy("string");
964 str
= appendString("enum ", uintOutputTypes
[type
->size
]);
968 sprintf(buf
,"%d\0",type
->size
);
969 str
= appendString("array ",buf
);
973 sprintf(buf
,"%d\0",type
->size
);
974 str
= appendString("sequence ",buf
);
978 str
= allocAndCopy("struct");
982 str
= allocAndCopy("union");
986 error_callback(NULL
, "named type has no definition");
990 crc
= partial_crc32(str
,crc
);
993 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
995 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
996 crc
= getTypeChecksum(crc
,type
->nested_type
);
997 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
998 for(pos
=0; pos
< type
->fields
.position
; pos
++){
999 fld
= (field
*) type
->fields
.array
[pos
];
1000 crc
= partial_crc32(fld
->name
,crc
);
1001 crc
= getTypeChecksum(crc
, fld
->type
);
1003 }else if(type
->type
== ENUM
){
1004 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1005 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1012 /* Event type descriptors */
1013 void freeType(type_descriptor
* tp
)
1018 if(tp
->fmt
!= NULL
) free(tp
->fmt
);
1019 if(tp
->type
== ENUM
) {
1020 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1021 free(tp
->labels
.array
[pos2
]);
1023 sequence_dispose(&(tp
->labels
));
1025 if(tp
->type
== STRUCT
) {
1026 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1027 f
= (field
*) tp
->fields
.array
[pos2
];
1029 free(f
->description
);
1032 sequence_dispose(&(tp
->fields
));
1036 void freeNamedType(table
* t
)
1039 type_descriptor
* td
;
1041 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1042 free((char *)t
->keys
.array
[pos
]);
1043 td
= (type_descriptor
*)t
->values
.array
[pos
];
1049 void freeTypes(sequence
*t
)
1052 type_descriptor
*tp
;
1055 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1056 tp
= (type_descriptor
*)t
->array
[pos
];
1062 void freeEvents(sequence
*t
)
1067 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1068 ev
= (event
*) t
->array
[pos
];
1070 free(ev
->description
);
1077 /* Extensible array */
1079 void sequence_init(sequence
*t
)
1083 t
->array
= (void **)memAlloc(t
->size
* sizeof(void *));
1086 void sequence_dispose(sequence
*t
)
1093 void sequence_push(sequence
*t
, void *elem
)
1097 if(t
->position
>= t
->size
) {
1099 t
->array
= (void **)memAlloc(t
->size
* 2 * sizeof(void *));
1100 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1101 t
->size
= t
->size
* 2;
1104 t
->array
[t
->position
] = elem
;
1108 void *sequence_pop(sequence
*t
)
1110 return t
->array
[t
->position
--];
1114 /* Hash table API, implementation is just linear search for now */
1116 void table_init(table
*t
)
1118 sequence_init(&(t
->keys
));
1119 sequence_init(&(t
->values
));
1122 void table_dispose(table
*t
)
1124 sequence_dispose(&(t
->keys
));
1125 sequence_dispose(&(t
->values
));
1128 void table_insert(table
*t
, char *key
, void *value
)
1130 sequence_push(&(t
->keys
),key
);
1131 sequence_push(&(t
->values
),value
);
1134 void *table_find(table
*t
, char *key
)
1137 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1138 if(strcmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1139 return(t
->values
.array
[pos
]);
1144 void table_insert_int(table
*t
, int *key
, void *value
)
1146 sequence_push(&(t
->keys
),key
);
1147 sequence_push(&(t
->values
),value
);
1150 void *table_find_int(table
*t
, int *key
)
1153 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1154 if(*key
== *(int *)t
->keys
.array
[pos
])
1155 return(t
->values
.array
[pos
]);
1161 /* Concatenate strings */
1163 char *appendString(char *s
, char *suffix
)
1166 if(suffix
== NULL
) return s
;
1168 tmp
= (char *)memAlloc(strlen(s
) + strlen(suffix
) + 1);
This page took 0.052533 seconds and 3 git commands to generate.