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 Copyright (C) 2005, Mathieu Desnoyers
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; version 2 of the License.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* This program reads the ".xml" event definitions input files
25 and constructs structure for each event.
27 The program uses a very simple tokenizer, called from a hand written
28 recursive descent parser to fill a data structure describing the events.
29 The result is a sequence of events definitions which refer to type
32 A table of named types is maintained to allow refering to types by name
33 when the same type is used at several places. Finally a sequence of
34 all types is maintained to facilitate the freeing of all type
35 information when the processing of an ".xml" file is finished. */
46 #include <linux/errno.h>
52 /*****************************************************************************
54 * getSize : translate from string to integer
56 * in : input file handle
59 *****************************************************************************/
61 int getSize(parse_file
*in
)
66 if(in
->type
== NUMBER
) {
67 if(g_ascii_strcasecmp(token
,"1") == 0) return 0;
68 else if(g_ascii_strcasecmp(token
,"2") == 0) return 1;
69 else if(g_ascii_strcasecmp(token
,"4") == 0) return 2;
70 else if(g_ascii_strcasecmp(token
,"8") == 0) return 3;
72 else if(in
->type
== NAME
) {
73 if(g_ascii_strcasecmp(token
,"short") == 0) return 4;
74 else if(g_ascii_strcasecmp(token
,"medium") == 0) return 5;
75 else if(g_ascii_strcasecmp(token
,"long") == 0) return 6;
77 in
->error(in
,"incorrect size specification");
81 /*****************************************************************************
83 * error_callback : print out error info
85 * in : input file handle
86 * msg : message to be printed
87 ****************************************************************************/
89 void error_callback(parse_file
*in
, char *msg
)
92 g_printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
97 /**************************************************************************
99 * getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute
100 * getValueStrAttribute
102 * Read the attribute from the input file.
105 * in , input file handle.
108 * address of the attribute.
110 **************************************************************************/
112 gchar
* getNameAttribute(parse_file
*in
)
119 if(g_ascii_strcasecmp("name",token
))in
->error(in
,"name was expected");
122 status
= seekNextChar(in
, &car
);
123 if(status
== G_IO_STATUS_EOF
|| status
== G_IO_STATUS_ERROR
)
124 in
->error(in
,"name was expected");
125 else if(car
== '\"') token
= getQuotedString(in
);
126 else token
= getName(in
);
130 char * getFormatAttribute(parse_file
*in
)
134 //format is an option
135 token
= getToken(in
);
136 if(g_ascii_strcasecmp("/",token
) == 0 || g_ascii_strcasecmp(">",token
) == 0){
141 if(g_ascii_strcasecmp("format",token
))in
->error(in
,"format was expected");
143 token
= getQuotedString(in
);
147 int getSizeAttribute(parse_file
*in
)
149 /* skip name and equal */
156 int getValueAttribute(parse_file
*in
)
158 /* skip name and equal */
162 return getNumber(in
);
165 //for <label name=label_name value=n/>, value is an option
166 char * getValueStrAttribute(parse_file
*in
)
170 token
= getToken(in
);
171 if(g_ascii_strcasecmp("/",token
) == 0){
176 if(g_ascii_strcasecmp("value",token
))in
->error(in
,"value was expected");
178 token
= getToken(in
);
179 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
183 char * getDescription(parse_file
*in
)
188 GError
* error
= NULL
;
192 getLAnglebracket(in
);
194 if(g_ascii_strcasecmp("description",token
)){
195 g_io_channel_seek_position(in
->channel
, pos
-(in
->pos
), G_SEEK_CUR
, &error
);
197 g_warning("Can not seek file: \n%s\n", error
->message
);
199 } else in
->pos
= pos
;
204 getRAnglebracket(in
);
207 while((g_io_channel_read_unichar(in
->channel
, &car
, &error
))
208 != G_IO_STATUS_EOF
) {
210 g_warning("Can not seek file: \n%s\n", error
->message
);
214 if(car
== '<') break;
215 if(car
== '\0') continue;
216 in
->buffer
[pos
] = car
;
219 if(car
== EOF
)in
->error(in
,"not a valid description");
220 in
->buffer
[pos
] = '\0';
222 str
= g_strdup(in
->buffer
);
226 if(g_ascii_strcasecmp("description", token
))in
->error(in
,"not a valid description");
227 getRAnglebracket(in
);
232 /*****************************************************************************
234 * parseFacility : generate event list
236 * in : input file handle
237 * fac : empty facility
239 * fac : facility filled with event list
240 ****************************************************************************/
242 void parseFacility(parse_file
*in
, facility_t
* fac
)
247 fac
->name
= g_strdup(getNameAttribute(in
));
248 getRAnglebracket(in
);
250 fac
->description
= getDescription(in
);
253 getLAnglebracket(in
);
255 token
= getToken(in
);
256 if(in
->type
== ENDFILE
)
257 in
->error(in
,"the definition of the facility is not finished");
259 if(g_ascii_strcasecmp("event",token
) == 0){
260 ev
= (event_t
*) g_new(event_t
,1);
261 sequence_push(&(fac
->events
),ev
);
262 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
263 }else if(g_ascii_strcasecmp("type",token
) == 0){
264 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
265 }else if(in
->type
== FORWARDSLASH
){
267 }else in
->error(in
,"event or type token expected\n");
271 if(g_ascii_strcasecmp("facility",token
)) in
->error(in
,"not the end of the facility");
272 getRAnglebracket(in
); //</facility>
275 /*****************************************************************************
277 * parseEvent : generate event from event definition
279 * in : input file handle
281 * unnamed_types : array of unamed types
282 * named_types : array of named types
284 * ev : new event (parameters are passed to it)
285 ****************************************************************************/
287 void parseEvent(parse_file
*in
, event_t
* ev
, sequence
* unnamed_types
,
292 //<event name=eventtype_name>
293 ev
->name
= g_strdup(getNameAttribute(in
));
294 getRAnglebracket(in
);
296 //<description>...</descriptio>
297 ev
->description
= getDescription(in
);
299 //event can have STRUCT, TYPEREF or NOTHING
300 getLAnglebracket(in
);
302 token
= getToken(in
);
303 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
305 }else if(in
->type
== NAME
){
306 if(g_ascii_strcasecmp("struct",token
)==0 || g_ascii_strcasecmp("typeref",token
)==0){
308 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
309 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
310 in
->error(in
,"type must be a struct");
311 }else in
->error(in
, "not a valid type");
313 getLAnglebracket(in
);
315 }else in
->error(in
,"not a struct type");
318 if(g_ascii_strcasecmp("event",token
))in
->error(in
,"not an event definition");
319 getRAnglebracket(in
); //</event>
322 /*****************************************************************************
324 * parseField : get field infomation from buffer
326 * in : input file handle
327 * t : type descriptor
328 * unnamed_types : array of unamed types
329 * named_types : array of named types
330 ****************************************************************************/
332 void parseFields(parse_file
*in
, type_descriptor
*t
, sequence
* unnamed_types
,
338 f
= g_new(type_fields
,1);
339 sequence_push(&(t
->fields
),f
);
341 //<field name=field_name> <description> <type> </field>
342 f
->name
= g_strdup(getNameAttribute(in
));
343 getRAnglebracket(in
);
345 f
->description
= getDescription(in
);
348 getLAnglebracket(in
);
349 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
351 getLAnglebracket(in
);
354 if(g_ascii_strcasecmp("field",token
))in
->error(in
,"not a valid field definition");
355 getRAnglebracket(in
); //</field>
359 /*****************************************************************************
361 * parseType : get type information, type can be :
363 * int(size,fmt); uint(size,fmt); float(size,fmt);
364 * string(fmt); enum(size,fmt,(label1,label2...))
366 * array(arraySize, type); sequence(lengthSize,type)
367 * struct(field(name,type,description)...)
371 * in : input file handle
372 * inType : a type descriptor
373 * unnamed_types : array of unamed types
374 * named_types : array of named types
376 * type_descriptor* : a type descriptor
377 ****************************************************************************/
379 type_descriptor
*parseType(parse_file
*in
, type_descriptor
*inType
,
380 sequence
* unnamed_types
, table
* named_types
)
386 t
= g_new(type_descriptor
,1);
390 sequence_push(unnamed_types
,t
);
396 if(g_ascii_strcasecmp(token
,"struct") == 0) {
398 getRAnglebracket(in
); //<struct>
399 getLAnglebracket(in
); //<field name=..>
400 token
= getToken(in
);
401 sequence_init(&(t
->fields
));
402 while(g_ascii_strcasecmp("field",token
) == 0){
403 parseFields(in
,t
, unnamed_types
, named_types
);
406 getLAnglebracket(in
);
407 token
= getToken(in
);
409 if(g_ascii_strcasecmp("/",token
))in
->error(in
,"not a valid structure definition");
411 if(g_ascii_strcasecmp("struct",token
)!=0)
412 in
->error(in
,"not a valid structure definition");
413 getRAnglebracket(in
); //</struct>
415 else if(g_ascii_strcasecmp(token
,"union") == 0) {
417 t
->size
= getSizeAttribute(in
);
418 getRAnglebracket(in
); //<union typecodesize=isize>
420 getLAnglebracket(in
); //<field name=..>
421 token
= getToken(in
);
422 sequence_init(&(t
->fields
));
423 while(g_ascii_strcasecmp("field",token
) == 0){
424 parseFields(in
,t
, unnamed_types
, named_types
);
427 getLAnglebracket(in
);
428 token
= getToken(in
);
430 if(g_ascii_strcasecmp("/",token
))in
->error(in
,"not a valid union definition");
432 if(g_ascii_strcasecmp("union",token
)!=0)
433 in
->error(in
,"not a valid union definition");
434 getRAnglebracket(in
); //</union>
436 else if(g_ascii_strcasecmp(token
,"array") == 0) {
438 t
->size
= getValueAttribute(in
);
439 getRAnglebracket(in
); //<array size=n>
441 getLAnglebracket(in
); //<type struct>
442 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
444 getLAnglebracket(in
); //</array>
447 if(g_ascii_strcasecmp("array",token
))in
->error(in
,"not a valid array definition");
448 getRAnglebracket(in
); //</array>
450 else if(g_ascii_strcasecmp(token
,"sequence") == 0) {
452 t
->size
= getSizeAttribute(in
);
453 getRAnglebracket(in
); //<array lengthsize=isize>
455 getLAnglebracket(in
); //<type struct>
456 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
458 getLAnglebracket(in
); //</sequence>
461 if(g_ascii_strcasecmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
462 getRAnglebracket(in
); //</sequence>
464 else if(g_ascii_strcasecmp(token
,"enum") == 0) {
467 sequence_init(&(t
->labels
));
468 t
->size
= getSizeAttribute(in
);
469 t
->fmt
= g_strdup(getFormatAttribute(in
));
470 getRAnglebracket(in
);
472 //<label name=label1 value=n/>
473 getLAnglebracket(in
);
474 token
= getToken(in
); //"label" or "/"
475 while(g_ascii_strcasecmp("label",token
) == 0){
476 str1
= g_strdup(getNameAttribute(in
));
477 token
= getValueStrAttribute(in
);
479 str
= g_strconcat(str1
,"=",token
,NULL
);
481 sequence_push(&(t
->labels
),str
);
483 sequence_push(&(t
->labels
),str1
);
486 getRAnglebracket(in
);
488 //next label definition
489 getLAnglebracket(in
);
490 token
= getToken(in
); //"label" or "/"
492 if(g_ascii_strcasecmp("/",token
))in
->error(in
, "not a valid enum definition");
494 if(g_ascii_strcasecmp("enum",token
))in
->error(in
, "not a valid enum definition");
495 getRAnglebracket(in
); //</label>
497 else if(g_ascii_strcasecmp(token
,"int") == 0) {
499 t
->size
= getSizeAttribute(in
);
500 t
->fmt
= g_strdup(getFormatAttribute(in
));
502 getRAnglebracket(in
);
504 else if(g_ascii_strcasecmp(token
,"uint") == 0) {
506 t
->size
= getSizeAttribute(in
);
507 t
->fmt
= g_strdup(getFormatAttribute(in
));
509 getRAnglebracket(in
);
511 else if(g_ascii_strcasecmp(token
,"float") == 0) {
513 t
->size
= getSizeAttribute(in
);
514 t
->fmt
= g_strdup(getFormatAttribute(in
));
516 getRAnglebracket(in
);
518 else if(g_ascii_strcasecmp(token
,"string") == 0) {
520 t
->fmt
= g_strdup(getFormatAttribute(in
));
522 getRAnglebracket(in
);
524 else if(g_ascii_strcasecmp(token
,"typeref") == 0){
525 // Must be a named type
527 in
->error(in
,"Named type cannot refer to a named type");
530 sequence_pop(unnamed_types
);
531 token
= getNameAttribute(in
);
532 t
= find_named_type(token
, named_types
);
533 getForwardslash(in
); //<typeref name=type_name/>
534 getRAnglebracket(in
);
537 }else in
->error(in
,"not a valid type");
542 /*****************************************************************************
544 * find_named_type : find a named type from hash table
547 * named_types : array of named types
549 * type_descriptor * : a type descriptor
550 *****************************************************************************/
552 type_descriptor
* find_named_type(gchar
*name
, table
* named_types
)
556 t
= table_find(named_types
,name
);
558 t
= g_new(type_descriptor
,1);
559 t
->type_name
= g_strdup(name
);
562 table_insert(named_types
,t
->type_name
,t
);
563 // table_insert(named_types,g_strdup(name),t);
568 /*****************************************************************************
570 * parseTypeDefinition : get type information from type definition
572 * in : input file handle
573 * unnamed_types : array of unamed types
574 * named_types : array of named types
575 *****************************************************************************/
577 void parseTypeDefinition(parse_file
* in
, sequence
* unnamed_types
,
583 token
= getNameAttribute(in
);
584 t
= find_named_type(token
, named_types
);
586 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
587 getRAnglebracket(in
); //<type name=type_name>
588 getLAnglebracket(in
); //<struct>
590 if(g_ascii_strcasecmp("struct",token
))in
->error(in
,"not a valid type definition");
592 parseType(in
,t
, unnamed_types
, named_types
);
595 getLAnglebracket(in
);
598 if(g_ascii_strcasecmp("type",token
))in
->error(in
,"not a valid type definition");
599 getRAnglebracket(in
); //</type>
602 /**************************************************************************
604 * getComa, getName, getNumber, getEqual
606 * Read a token from the input file, check its type, return it scontent.
609 * in , input file handle.
612 * address of token content.
614 **************************************************************************/
616 char *getName(parse_file
* in
)
620 token
= getToken(in
);
621 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
625 int getNumber(parse_file
* in
)
629 token
= getToken(in
);
630 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
634 char *getForwardslash(parse_file
* in
)
638 token
= getToken(in
);
639 if(in
->type
!= FORWARDSLASH
) in
->error(in
, "forward slash token was expected");
643 char *getLAnglebracket(parse_file
* in
)
647 token
= getToken(in
);
648 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
652 char *getRAnglebracket(parse_file
* in
)
656 token
= getToken(in
);
657 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
661 char *getQuotedString(parse_file
* in
)
665 token
= getToken(in
);
666 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
670 char * getEqual(parse_file
*in
)
674 token
= getToken(in
);
675 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
679 gunichar
seekNextChar(parse_file
*in
, gunichar
*car
)
681 GError
* error
= NULL
;
686 status
= g_io_channel_read_unichar(in
->channel
, car
, &error
);
689 g_warning("Can not read file: \n%s\n", error
->message
);
695 if(!g_unichar_isspace(*car
)) {
696 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
698 g_warning("Can not seek file: \n%s\n", error
->message
);
705 } while(status
!= G_IO_STATUS_EOF
&& status
!= G_IO_STATUS_ERROR
);
711 /******************************************************************
713 * getToken, ungetToken
715 * Read a token from the input file and return its type and content.
716 * Line numbers are accounted for and whitespace/comments are skipped.
719 * in, input file handle.
722 * address of token content.
724 ******************************************************************/
726 void ungetToken(parse_file
* in
)
731 gchar
*getToken(parse_file
* in
)
734 int pos
= 0, escaped
;
735 GError
* error
= NULL
;
742 /* skip whitespace and comments */
744 while((g_io_channel_read_unichar(in
->channel
, &car
, &error
))
745 != G_IO_STATUS_EOF
) {
748 g_warning("Can not read file: \n%s\n", error
->message
);
753 g_io_channel_read_unichar(in
->channel
, &car1
, &error
);
755 g_warning("Can not read file: \n%s\n", error
->message
);
759 if(car1
== '*') skipComment(in
);
760 else if(car1
== '/') skipEOL(in
);
762 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
764 g_warning("Can not seek file: \n%s\n", error
->message
);
770 else if(car
== '\n') in
->lineno
++;
771 else if(!g_unichar_isspace(car
)) break;
778 in
->type
= FORWARDSLASH
;
779 in
->buffer
[pos
] = car
;
783 in
->type
= LANGLEBRACKET
;
784 in
->buffer
[pos
] = car
;
788 in
->type
= RANGLEBRACKET
;
789 in
->buffer
[pos
] = car
;
794 in
->buffer
[pos
] = car
;
799 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
800 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
803 g_warning("Can not read file: \n%s\n", error
->message
);
807 if(car
== '\\' && escaped
== 0) {
808 in
->buffer
[pos
] = car
;
813 if(car
== '"' && escaped
== 0) break;
814 if(car
== '\n' && escaped
== 0) {
815 in
->error(in
, "non escaped newline inside quoted string");
817 if(car
== '\n') in
->lineno
++;
818 in
->buffer
[pos
] = car
;
822 if(car
== EOF
) in
->error(in
,"no ending quotemark");
823 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
824 in
->type
= QUOTEDSTRING
;
827 if(g_unichar_isdigit(car
)) {
828 in
->buffer
[pos
] = car
;
830 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
831 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
834 g_warning("Can not read file: \n%s\n", error
->message
);
839 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
841 g_warning("Can not seek file: \n%s\n", error
->message
);
846 in
->buffer
[pos
] = car
;
850 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
852 g_warning("Can not seek file: \n%s\n", error
->message
);
856 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
859 else if(g_unichar_isalpha(car
)) {
862 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
863 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
866 g_warning("Can not read file: \n%s\n", error
->message
);
870 if(!(g_unichar_isalnum(car
) || car
== '_')) {
871 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
873 g_warning("Can not seek file: \n%s\n", error
->message
);
878 in
->buffer
[pos
] = car
;
882 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
884 g_warning("Can not seek file: \n%s\n", error
->message
);
888 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
891 else in
->error(in
, "invalid character, unrecognized token");
897 void skipComment(parse_file
* in
)
900 GError
* error
= NULL
;
902 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
903 != G_IO_STATUS_EOF
) {
906 g_warning("Can not read file: \n%s\n", error
->message
);
910 if(car
== '\n') in
->lineno
++;
911 else if(car
== '*') {
913 g_io_channel_read_unichar(in
->channel
, &car
, &error
);
915 g_warning("Can not read file: \n%s\n", error
->message
);
920 if(car
== '/') return;
922 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
924 g_warning("Can not seek file: \n%s\n", error
->message
);
930 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
933 void skipEOL(parse_file
* in
)
936 GError
* error
= NULL
;
938 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
939 != G_IO_STATUS_EOF
) {
941 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
943 g_warning("Can not seek file: \n%s\n", error
->message
);
950 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
952 g_warning("Can not seek file: \n%s\n", error
->message
);
958 /*****************************************************************************
960 * checkNamedTypesImplemented : check if all named types have definition
961 * returns -1 on error, 0 if ok
962 ****************************************************************************/
964 int checkNamedTypesImplemented(table
* named_types
)
970 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
971 t
= (type_descriptor
*) named_types
->values
.array
[pos
];
973 sprintf(str
,"named type '%s' has no definition",
974 (char*)named_types
->keys
.array
[pos
]);
975 error_callback(NULL
,str
);
983 /*****************************************************************************
985 * generateChecksum : generate checksum for the facility
987 * facName : name of facility
989 * checksum : checksum for the facility
990 ****************************************************************************/
992 int generateChecksum(char* facName
, guint32
* checksum
, sequence
* events
)
999 crc
= crc32(facName
);
1000 for(pos
= 0; pos
< events
->position
; pos
++){
1001 ev
= (event_t
*)(events
->array
[pos
]);
1002 crc
= partial_crc32(ev
->name
,crc
);
1003 if(!ev
->type
) continue; //event without type
1004 if(ev
->type
->type
!= STRUCT
){
1005 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
1006 error_callback(NULL
, str
);
1009 crc
= getTypeChecksum(crc
, ev
->type
);
1015 /*****************************************************************************
1017 * getTypeChecksum : generate checksum by type info
1019 * crc : checksum generated so far
1020 * type : type descriptor containing type info
1022 * unsigned long : checksum
1023 *****************************************************************************/
1025 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor
* type
)
1027 unsigned long crc
= aCrc
;
1028 char * str
= NULL
, buf
[16];
1034 str
= intOutputTypes
[type
->size
];
1037 str
= uintOutputTypes
[type
->size
];
1040 str
= floatOutputTypes
[type
->size
];
1043 str
= g_strdup("string");
1047 str
= g_strconcat("enum ", uintOutputTypes
[type
->size
], NULL
);
1051 sprintf(buf
,"%d",type
->size
);
1052 str
= g_strconcat("array ",buf
, NULL
);
1056 sprintf(buf
,"%d",type
->size
);
1057 str
= g_strconcat("sequence ",buf
, NULL
);
1061 str
= g_strdup("struct");
1065 str
= g_strdup("union");
1069 error_callback(NULL
, "named type has no definition");
1073 crc
= partial_crc32(str
,crc
);
1074 if(flag
) g_free(str
);
1076 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1078 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1079 crc
= getTypeChecksum(crc
,type
->nested_type
);
1080 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1081 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1082 fld
= (type_fields
*) type
->fields
.array
[pos
];
1083 crc
= partial_crc32(fld
->name
,crc
);
1084 crc
= getTypeChecksum(crc
, fld
->type
);
1086 }else if(type
->type
== ENUM
){
1087 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1088 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1095 /* Event type descriptors */
1096 void freeType(type_descriptor
* tp
)
1101 if(tp
->fmt
!= NULL
) g_free(tp
->fmt
);
1102 if(tp
->type
== ENUM
) {
1103 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1104 g_free(tp
->labels
.array
[pos2
]);
1106 sequence_dispose(&(tp
->labels
));
1108 if(tp
->type
== STRUCT
) {
1109 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1110 f
= (type_fields
*) tp
->fields
.array
[pos2
];
1112 g_free(f
->description
);
1115 sequence_dispose(&(tp
->fields
));
1119 void freeNamedType(table
* t
)
1122 type_descriptor
* td
;
1124 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1125 g_free((char *)t
->keys
.array
[pos
]);
1126 td
= (type_descriptor
*)t
->values
.array
[pos
];
1132 void freeTypes(sequence
*t
)
1135 type_descriptor
*tp
;
1137 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1138 tp
= (type_descriptor
*)t
->array
[pos
];
1144 void freeEvents(sequence
*t
)
1149 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1150 ev
= (event_t
*) t
->array
[pos
];
1152 g_free(ev
->description
);
1159 /* Extensible array */
1161 void sequence_init(sequence
*t
)
1165 t
->array
= g_new(void*, t
->size
);
1168 void sequence_dispose(sequence
*t
)
1175 void sequence_push(sequence
*t
, void *elem
)
1179 if(t
->position
>= t
->size
) {
1181 t
->array
= g_new(void*, 2*t
->size
);
1182 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1183 t
->size
= t
->size
* 2;
1186 t
->array
[t
->position
] = elem
;
1190 void *sequence_pop(sequence
*t
)
1192 return t
->array
[t
->position
--];
1196 /* Hash table API, implementation is just linear search for now */
1198 void table_init(table
*t
)
1200 sequence_init(&(t
->keys
));
1201 sequence_init(&(t
->values
));
1204 void table_dispose(table
*t
)
1206 sequence_dispose(&(t
->keys
));
1207 sequence_dispose(&(t
->values
));
1210 void table_insert(table
*t
, char *key
, void *value
)
1212 sequence_push(&(t
->keys
),key
);
1213 sequence_push(&(t
->values
),value
);
1216 void *table_find(table
*t
, char *key
)
1219 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1220 if(g_ascii_strcasecmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1221 return(t
->values
.array
[pos
]);
1226 void table_insert_int(table
*t
, int *key
, void *value
)
1228 sequence_push(&(t
->keys
),key
);
1229 sequence_push(&(t
->values
),value
);
1232 void *table_find_int(table
*t
, int *key
)
1235 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1236 if(*key
== *(int *)t
->keys
.array
[pos
])
1237 return(t
->values
.array
[pos
]);
This page took 0.055952 seconds and 4 git commands to generate.