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. */
42 #include <linux/errno.h>
48 /*****************************************************************************
50 * getSize : translate from string to integer
52 * in : input file handle
55 *****************************************************************************/
57 int getSize(parse_file
*in
)
62 if(in
->type
== NUMBER
) {
63 if(g_ascii_strcasecmp(token
,"1") == 0) return 0;
64 else if(g_ascii_strcasecmp(token
,"2") == 0) return 1;
65 else if(g_ascii_strcasecmp(token
,"4") == 0) return 2;
66 else if(g_ascii_strcasecmp(token
,"8") == 0) return 3;
68 else if(in
->type
== NAME
) {
69 if(g_ascii_strcasecmp(token
,"short") == 0) return 4;
70 else if(g_ascii_strcasecmp(token
,"medium") == 0) return 5;
71 else if(g_ascii_strcasecmp(token
,"long") == 0) return 6;
73 in
->error(in
,"incorrect size specification");
77 /*****************************************************************************
79 * error_callback : print out error info
81 * in : input file handle
82 * msg : message to be printed
83 ****************************************************************************/
85 void error_callback(parse_file
*in
, char *msg
)
88 g_printf("Error in file %s, line %d: %s\n", in
->name
, in
->lineno
, msg
);
93 /**************************************************************************
95 * getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute
96 * getValueStrAttribute
98 * Read the attribute from the input file.
101 * in , input file handle.
104 * address of the attribute.
106 **************************************************************************/
108 gchar
* getNameAttribute(parse_file
*in
)
115 if(g_ascii_strcasecmp("name",token
))in
->error(in
,"name was expected");
118 status
= seekNextChar(in
, &car
);
119 if(status
== G_IO_STATUS_EOF
|| status
== G_IO_STATUS_ERROR
)
120 in
->error(in
,"name was expected");
121 else if(car
== '\"') token
= getQuotedString(in
);
122 else token
= getName(in
);
126 char * getFormatAttribute(parse_file
*in
)
130 //format is an option
131 token
= getToken(in
);
132 if(g_ascii_strcasecmp("/",token
) == 0 || g_ascii_strcasecmp(">",token
) == 0){
137 if(g_ascii_strcasecmp("format",token
))in
->error(in
,"format was expected");
139 token
= getQuotedString(in
);
143 int getSizeAttribute(parse_file
*in
)
145 /* skip name and equal */
152 int getValueAttribute(parse_file
*in
)
154 /* skip name and equal */
158 return getNumber(in
);
161 //for <label name=label_name value=n/>, value is an option
162 char * getValueStrAttribute(parse_file
*in
)
166 token
= getToken(in
);
167 if(g_ascii_strcasecmp("/",token
) == 0){
172 if(g_ascii_strcasecmp("value",token
))in
->error(in
,"value was expected");
174 token
= getToken(in
);
175 if(in
->type
!= NUMBER
) in
->error(in
,"number was expected");
179 char * getDescription(parse_file
*in
)
184 GError
* error
= NULL
;
188 getLAnglebracket(in
);
190 if(g_ascii_strcasecmp("description",token
)){
191 g_io_channel_seek_position(in
->channel
, pos
-(in
->pos
), G_SEEK_CUR
, &error
);
193 g_warning("Can not seek file: \n%s\n", error
->message
);
195 } else in
->pos
= pos
;
200 getRAnglebracket(in
);
203 while((g_io_channel_read_unichar(in
->channel
, &car
, &error
))
204 != G_IO_STATUS_EOF
) {
206 g_warning("Can not seek file: \n%s\n", error
->message
);
210 if(car
== '<') break;
211 if(car
== '\0') continue;
212 in
->buffer
[pos
] = car
;
215 if(car
== EOF
)in
->error(in
,"not a valid description");
216 in
->buffer
[pos
] = '\0';
218 str
= g_strdup(in
->buffer
);
222 if(g_ascii_strcasecmp("description", token
))in
->error(in
,"not a valid description");
223 getRAnglebracket(in
);
228 /*****************************************************************************
230 * parseFacility : generate event list
232 * in : input file handle
233 * fac : empty facility
235 * fac : facility filled with event list
236 ****************************************************************************/
238 void parseFacility(parse_file
*in
, facility_t
* fac
)
243 fac
->name
= g_strdup(getNameAttribute(in
));
244 getRAnglebracket(in
);
246 fac
->description
= getDescription(in
);
249 getLAnglebracket(in
);
251 token
= getToken(in
);
252 if(in
->type
== ENDFILE
)
253 in
->error(in
,"the definition of the facility is not finished");
255 if(g_ascii_strcasecmp("event",token
) == 0){
256 ev
= (event_t
*) g_new(event_t
,1);
257 sequence_push(&(fac
->events
),ev
);
258 parseEvent(in
,ev
, &(fac
->unnamed_types
), &(fac
->named_types
));
259 }else if(g_ascii_strcasecmp("type",token
) == 0){
260 parseTypeDefinition(in
, &(fac
->unnamed_types
), &(fac
->named_types
));
261 }else if(in
->type
== FORWARDSLASH
){
263 }else in
->error(in
,"event or type token expected\n");
267 if(g_ascii_strcasecmp("facility",token
)) in
->error(in
,"not the end of the facility");
268 getRAnglebracket(in
); //</facility>
271 /*****************************************************************************
273 * parseEvent : generate event from event definition
275 * in : input file handle
277 * unnamed_types : array of unamed types
278 * named_types : array of named types
280 * ev : new event (parameters are passed to it)
281 ****************************************************************************/
283 void parseEvent(parse_file
*in
, event_t
* ev
, sequence
* unnamed_types
,
288 //<event name=eventtype_name>
289 ev
->name
= g_strdup(getNameAttribute(in
));
290 getRAnglebracket(in
);
292 //<description>...</descriptio>
293 ev
->description
= getDescription(in
);
295 //event can have STRUCT, TYPEREF or NOTHING
296 getLAnglebracket(in
);
298 token
= getToken(in
);
299 if(in
->type
== FORWARDSLASH
){ //</event> NOTHING
301 }else if(in
->type
== NAME
){
302 if(g_ascii_strcasecmp("struct",token
)==0 || g_ascii_strcasecmp("typeref",token
)==0){
304 ev
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
305 if(ev
->type
->type
!= STRUCT
&& ev
->type
->type
!= NONE
)
306 in
->error(in
,"type must be a struct");
307 }else in
->error(in
, "not a valid type");
309 getLAnglebracket(in
);
311 }else in
->error(in
,"not a struct type");
314 if(g_ascii_strcasecmp("event",token
))in
->error(in
,"not an event definition");
315 getRAnglebracket(in
); //</event>
318 /*****************************************************************************
320 * parseField : get field infomation from buffer
322 * in : input file handle
323 * t : type descriptor
324 * unnamed_types : array of unamed types
325 * named_types : array of named types
326 ****************************************************************************/
328 void parseFields(parse_file
*in
, type_descriptor
*t
, sequence
* unnamed_types
,
334 f
= g_new(type_fields
,1);
335 sequence_push(&(t
->fields
),f
);
337 //<field name=field_name> <description> <type> </field>
338 f
->name
= g_strdup(getNameAttribute(in
));
339 getRAnglebracket(in
);
341 f
->description
= getDescription(in
);
344 getLAnglebracket(in
);
345 f
->type
= parseType(in
,NULL
, unnamed_types
, named_types
);
347 getLAnglebracket(in
);
350 if(g_ascii_strcasecmp("field",token
))in
->error(in
,"not a valid field definition");
351 getRAnglebracket(in
); //</field>
355 /*****************************************************************************
357 * parseType : get type information, type can be :
359 * int(size,fmt); uint(size,fmt); float(size,fmt);
360 * string(fmt); enum(size,fmt,(label1,label2...))
362 * array(arraySize, type); sequence(lengthSize,type)
363 * struct(field(name,type,description)...)
367 * in : input file handle
368 * inType : a type descriptor
369 * unnamed_types : array of unamed types
370 * named_types : array of named types
372 * type_descriptor* : a type descriptor
373 ****************************************************************************/
375 type_descriptor
*parseType(parse_file
*in
, type_descriptor
*inType
,
376 sequence
* unnamed_types
, table
* named_types
)
382 t
= g_new(type_descriptor
,1);
386 sequence_push(unnamed_types
,t
);
392 if(g_ascii_strcasecmp(token
,"struct") == 0) {
394 getRAnglebracket(in
); //<struct>
395 getLAnglebracket(in
); //<field name=..>
396 token
= getToken(in
);
397 sequence_init(&(t
->fields
));
398 while(g_ascii_strcasecmp("field",token
) == 0){
399 parseFields(in
,t
, unnamed_types
, named_types
);
402 getLAnglebracket(in
);
403 token
= getToken(in
);
405 if(g_ascii_strcasecmp("/",token
))in
->error(in
,"not a valid structure definition");
407 if(g_ascii_strcasecmp("struct",token
)!=0)
408 in
->error(in
,"not a valid structure definition");
409 getRAnglebracket(in
); //</struct>
411 else if(g_ascii_strcasecmp(token
,"union") == 0) {
413 t
->size
= getSizeAttribute(in
);
414 getRAnglebracket(in
); //<union typecodesize=isize>
416 getLAnglebracket(in
); //<field name=..>
417 token
= getToken(in
);
418 sequence_init(&(t
->fields
));
419 while(g_ascii_strcasecmp("field",token
) == 0){
420 parseFields(in
,t
, unnamed_types
, named_types
);
423 getLAnglebracket(in
);
424 token
= getToken(in
);
426 if(g_ascii_strcasecmp("/",token
))in
->error(in
,"not a valid union definition");
428 if(g_ascii_strcasecmp("union",token
)!=0)
429 in
->error(in
,"not a valid union definition");
430 getRAnglebracket(in
); //</union>
432 else if(g_ascii_strcasecmp(token
,"array") == 0) {
434 t
->size
= getValueAttribute(in
);
435 getRAnglebracket(in
); //<array size=n>
437 getLAnglebracket(in
); //<type struct>
438 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
440 getLAnglebracket(in
); //</array>
443 if(g_ascii_strcasecmp("array",token
))in
->error(in
,"not a valid array definition");
444 getRAnglebracket(in
); //</array>
446 else if(g_ascii_strcasecmp(token
,"sequence") == 0) {
448 t
->size
= getSizeAttribute(in
);
449 getRAnglebracket(in
); //<array lengthsize=isize>
451 getLAnglebracket(in
); //<type struct>
452 t
->nested_type
= parseType(in
,NULL
, unnamed_types
, named_types
);
454 getLAnglebracket(in
); //</sequence>
457 if(g_ascii_strcasecmp("sequence",token
))in
->error(in
,"not a valid sequence definition");
458 getRAnglebracket(in
); //</sequence>
460 else if(g_ascii_strcasecmp(token
,"enum") == 0) {
463 sequence_init(&(t
->labels
));
464 t
->size
= getSizeAttribute(in
);
465 t
->fmt
= g_strdup(getFormatAttribute(in
));
466 getRAnglebracket(in
);
468 //<label name=label1 value=n/>
469 getLAnglebracket(in
);
470 token
= getToken(in
); //"label" or "/"
471 while(g_ascii_strcasecmp("label",token
) == 0){
472 str1
= g_strdup(getNameAttribute(in
));
473 token
= getValueStrAttribute(in
);
475 str
= g_strconcat(str1
,"=",token
,NULL
);
477 sequence_push(&(t
->labels
),str
);
479 sequence_push(&(t
->labels
),str1
);
482 getRAnglebracket(in
);
484 //next label definition
485 getLAnglebracket(in
);
486 token
= getToken(in
); //"label" or "/"
488 if(g_ascii_strcasecmp("/",token
))in
->error(in
, "not a valid enum definition");
490 if(g_ascii_strcasecmp("enum",token
))in
->error(in
, "not a valid enum definition");
491 getRAnglebracket(in
); //</label>
493 else if(g_ascii_strcasecmp(token
,"int") == 0) {
495 t
->size
= getSizeAttribute(in
);
496 t
->fmt
= g_strdup(getFormatAttribute(in
));
498 getRAnglebracket(in
);
500 else if(g_ascii_strcasecmp(token
,"uint") == 0) {
502 t
->size
= getSizeAttribute(in
);
503 t
->fmt
= g_strdup(getFormatAttribute(in
));
505 getRAnglebracket(in
);
507 else if(g_ascii_strcasecmp(token
,"float") == 0) {
509 t
->size
= getSizeAttribute(in
);
510 t
->fmt
= g_strdup(getFormatAttribute(in
));
512 getRAnglebracket(in
);
514 else if(g_ascii_strcasecmp(token
,"string") == 0) {
516 t
->fmt
= g_strdup(getFormatAttribute(in
));
518 getRAnglebracket(in
);
520 else if(g_ascii_strcasecmp(token
,"typeref") == 0){
521 // Must be a named type
523 in
->error(in
,"Named type cannot refer to a named type");
526 sequence_pop(unnamed_types
);
527 token
= getNameAttribute(in
);
528 t
= find_named_type(token
, named_types
);
529 getForwardslash(in
); //<typeref name=type_name/>
530 getRAnglebracket(in
);
533 }else in
->error(in
,"not a valid type");
538 /*****************************************************************************
540 * find_named_type : find a named type from hash table
543 * named_types : array of named types
545 * type_descriptor * : a type descriptor
546 *****************************************************************************/
548 type_descriptor
* find_named_type(gchar
*name
, table
* named_types
)
552 t
= table_find(named_types
,name
);
554 t
= g_new(type_descriptor
,1);
555 t
->type_name
= g_strdup(name
);
558 table_insert(named_types
,t
->type_name
,t
);
559 // table_insert(named_types,g_strdup(name),t);
564 /*****************************************************************************
566 * parseTypeDefinition : get type information from type definition
568 * in : input file handle
569 * unnamed_types : array of unamed types
570 * named_types : array of named types
571 *****************************************************************************/
573 void parseTypeDefinition(parse_file
* in
, sequence
* unnamed_types
,
579 token
= getNameAttribute(in
);
580 t
= find_named_type(token
, named_types
);
582 if(t
->type
!= NONE
) in
->error(in
,"redefinition of named type");
583 getRAnglebracket(in
); //<type name=type_name>
584 getLAnglebracket(in
); //<struct>
586 if(g_ascii_strcasecmp("struct",token
))in
->error(in
,"not a valid type definition");
588 parseType(in
,t
, unnamed_types
, named_types
);
591 getLAnglebracket(in
);
594 if(g_ascii_strcasecmp("type",token
))in
->error(in
,"not a valid type definition");
595 getRAnglebracket(in
); //</type>
598 /**************************************************************************
600 * getComa, getName, getNumber, getEqual
602 * Read a token from the input file, check its type, return it scontent.
605 * in , input file handle.
608 * address of token content.
610 **************************************************************************/
612 char *getName(parse_file
* in
)
616 token
= getToken(in
);
617 if(in
->type
!= NAME
) in
->error(in
,"Name token was expected");
621 int getNumber(parse_file
* in
)
625 token
= getToken(in
);
626 if(in
->type
!= NUMBER
) in
->error(in
, "Number token was expected");
630 char *getForwardslash(parse_file
* in
)
634 token
= getToken(in
);
635 if(in
->type
!= FORWARDSLASH
) in
->error(in
, "forward slash token was expected");
639 char *getLAnglebracket(parse_file
* in
)
643 token
= getToken(in
);
644 if(in
->type
!= LANGLEBRACKET
) in
->error(in
, "Left angle bracket was expected");
648 char *getRAnglebracket(parse_file
* in
)
652 token
= getToken(in
);
653 if(in
->type
!= RANGLEBRACKET
) in
->error(in
, "Right angle bracket was expected");
657 char *getQuotedString(parse_file
* in
)
661 token
= getToken(in
);
662 if(in
->type
!= QUOTEDSTRING
) in
->error(in
, "quoted string was expected");
666 char * getEqual(parse_file
*in
)
670 token
= getToken(in
);
671 if(in
->type
!= EQUAL
) in
->error(in
, "equal was expected");
675 gunichar
seekNextChar(parse_file
*in
, gunichar
*car
)
677 GError
* error
= NULL
;
682 status
= g_io_channel_read_unichar(in
->channel
, car
, &error
);
685 g_warning("Can not read file: \n%s\n", error
->message
);
691 if(!g_unichar_isspace(*car
)) {
692 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
694 g_warning("Can not seek file: \n%s\n", error
->message
);
701 } while(status
!= G_IO_STATUS_EOF
&& status
!= G_IO_STATUS_ERROR
);
707 /******************************************************************
709 * getToken, ungetToken
711 * Read a token from the input file and return its type and content.
712 * Line numbers are accounted for and whitespace/comments are skipped.
715 * in, input file handle.
718 * address of token content.
720 ******************************************************************/
722 void ungetToken(parse_file
* in
)
727 gchar
*getToken(parse_file
* in
)
730 int pos
= 0, escaped
;
731 GError
* error
= NULL
;
738 /* skip whitespace and comments */
740 while((g_io_channel_read_unichar(in
->channel
, &car
, &error
))
741 != G_IO_STATUS_EOF
) {
744 g_warning("Can not read file: \n%s\n", error
->message
);
749 g_io_channel_read_unichar(in
->channel
, &car1
, &error
);
751 g_warning("Can not read file: \n%s\n", error
->message
);
755 if(car1
== '*') skipComment(in
);
756 else if(car1
== '/') skipEOL(in
);
758 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
760 g_warning("Can not seek file: \n%s\n", error
->message
);
766 else if(car
== '\n') in
->lineno
++;
767 else if(!g_unichar_isspace(car
)) break;
774 in
->type
= FORWARDSLASH
;
775 in
->buffer
[pos
] = car
;
779 in
->type
= LANGLEBRACKET
;
780 in
->buffer
[pos
] = car
;
784 in
->type
= RANGLEBRACKET
;
785 in
->buffer
[pos
] = car
;
790 in
->buffer
[pos
] = car
;
795 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
796 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
799 g_warning("Can not read file: \n%s\n", error
->message
);
803 if(car
== '\\' && escaped
== 0) {
804 in
->buffer
[pos
] = car
;
809 if(car
== '"' && escaped
== 0) break;
810 if(car
== '\n' && escaped
== 0) {
811 in
->error(in
, "non escaped newline inside quoted string");
813 if(car
== '\n') in
->lineno
++;
814 in
->buffer
[pos
] = car
;
818 if(car
== EOF
) in
->error(in
,"no ending quotemark");
819 if(pos
== BUFFER_SIZE
) in
->error(in
, "quoted string token too large");
820 in
->type
= QUOTEDSTRING
;
823 if(g_unichar_isdigit(car
)) {
824 in
->buffer
[pos
] = car
;
826 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
827 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
830 g_warning("Can not read file: \n%s\n", error
->message
);
835 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
837 g_warning("Can not seek file: \n%s\n", error
->message
);
842 in
->buffer
[pos
] = car
;
846 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
848 g_warning("Can not seek file: \n%s\n", error
->message
);
852 if(pos
== BUFFER_SIZE
) in
->error(in
, "number token too large");
855 else if(g_unichar_isalpha(car
)) {
858 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
859 != G_IO_STATUS_EOF
&& pos
< BUFFER_SIZE
) {
862 g_warning("Can not read file: \n%s\n", error
->message
);
866 if(!(g_unichar_isalnum(car
) || car
== '_')) {
867 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
869 g_warning("Can not seek file: \n%s\n", error
->message
);
874 in
->buffer
[pos
] = car
;
878 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
880 g_warning("Can not seek file: \n%s\n", error
->message
);
884 if(pos
== BUFFER_SIZE
) in
->error(in
, "name token too large");
887 else in
->error(in
, "invalid character, unrecognized token");
893 void skipComment(parse_file
* in
)
896 GError
* error
= NULL
;
898 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
899 != G_IO_STATUS_EOF
) {
902 g_warning("Can not read file: \n%s\n", error
->message
);
906 if(car
== '\n') in
->lineno
++;
907 else if(car
== '*') {
909 g_io_channel_read_unichar(in
->channel
, &car
, &error
);
911 g_warning("Can not read file: \n%s\n", error
->message
);
916 if(car
== '/') return;
918 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
920 g_warning("Can not seek file: \n%s\n", error
->message
);
926 if(car
== EOF
) in
->error(in
,"comment begining with '/*' has no ending '*/'");
929 void skipEOL(parse_file
* in
)
932 GError
* error
= NULL
;
934 while(g_io_channel_read_unichar(in
->channel
, &car
, &error
)
935 != G_IO_STATUS_EOF
) {
937 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
939 g_warning("Can not seek file: \n%s\n", error
->message
);
946 g_io_channel_seek_position(in
->channel
, -1, G_SEEK_CUR
, &error
);
948 g_warning("Can not seek file: \n%s\n", error
->message
);
954 /*****************************************************************************
956 * checkNamedTypesImplemented : check if all named types have definition
957 * returns -1 on error, 0 if ok
958 ****************************************************************************/
960 int checkNamedTypesImplemented(table
* named_types
)
966 for(pos
= 0 ; pos
< named_types
->values
.position
; pos
++) {
967 t
= (type_descriptor
*) named_types
->values
.array
[pos
];
969 sprintf(str
,"named type '%s' has no definition",
970 (char*)named_types
->keys
.array
[pos
]);
971 error_callback(NULL
,str
);
979 /*****************************************************************************
981 * generateChecksum : generate checksum for the facility
983 * facName : name of facility
985 * checksum : checksum for the facility
986 ****************************************************************************/
988 int generateChecksum(char* facName
, guint32
* checksum
, sequence
* events
)
995 crc
= crc32(facName
);
996 for(pos
= 0; pos
< events
->position
; pos
++){
997 ev
= (event_t
*)(events
->array
[pos
]);
998 crc
= partial_crc32(ev
->name
,crc
);
999 if(!ev
->type
) continue; //event without type
1000 if(ev
->type
->type
!= STRUCT
){
1001 sprintf(str
,"event '%s' has a type other than STRUCT",ev
->name
);
1002 error_callback(NULL
, str
);
1005 crc
= getTypeChecksum(crc
, ev
->type
);
1011 /*****************************************************************************
1013 * getTypeChecksum : generate checksum by type info
1015 * crc : checksum generated so far
1016 * type : type descriptor containing type info
1018 * unsigned long : checksum
1019 *****************************************************************************/
1021 unsigned long getTypeChecksum(unsigned long aCrc
, type_descriptor
* type
)
1023 unsigned long crc
= aCrc
;
1024 char * str
= NULL
, buf
[16];
1030 str
= intOutputTypes
[type
->size
];
1033 str
= uintOutputTypes
[type
->size
];
1036 str
= floatOutputTypes
[type
->size
];
1039 str
= g_strdup("string");
1043 str
= g_strconcat("enum ", uintOutputTypes
[type
->size
], NULL
);
1047 sprintf(buf
,"%d",type
->size
);
1048 str
= g_strconcat("array ",buf
, NULL
);
1052 sprintf(buf
,"%d",type
->size
);
1053 str
= g_strconcat("sequence ",buf
, NULL
);
1057 str
= g_strdup("struct");
1061 str
= g_strdup("union");
1065 error_callback(NULL
, "named type has no definition");
1069 crc
= partial_crc32(str
,crc
);
1070 if(flag
) g_free(str
);
1072 if(type
->fmt
) crc
= partial_crc32(type
->fmt
,crc
);
1074 if(type
->type
== ARRAY
|| type
->type
== SEQUENCE
){
1075 crc
= getTypeChecksum(crc
,type
->nested_type
);
1076 }else if(type
->type
== STRUCT
|| type
->type
== UNION
){
1077 for(pos
=0; pos
< type
->fields
.position
; pos
++){
1078 fld
= (type_fields
*) type
->fields
.array
[pos
];
1079 crc
= partial_crc32(fld
->name
,crc
);
1080 crc
= getTypeChecksum(crc
, fld
->type
);
1082 }else if(type
->type
== ENUM
){
1083 for(pos
= 0; pos
< type
->labels
.position
; pos
++)
1084 crc
= partial_crc32((char*)type
->labels
.array
[pos
],crc
);
1091 /* Event type descriptors */
1092 void freeType(type_descriptor
* tp
)
1097 if(tp
->fmt
!= NULL
) g_free(tp
->fmt
);
1098 if(tp
->type
== ENUM
) {
1099 for(pos2
= 0; pos2
< tp
->labels
.position
; pos2
++) {
1100 g_free(tp
->labels
.array
[pos2
]);
1102 sequence_dispose(&(tp
->labels
));
1104 if(tp
->type
== STRUCT
) {
1105 for(pos2
= 0; pos2
< tp
->fields
.position
; pos2
++) {
1106 f
= (type_fields
*) tp
->fields
.array
[pos2
];
1108 g_free(f
->description
);
1111 sequence_dispose(&(tp
->fields
));
1115 void freeNamedType(table
* t
)
1118 type_descriptor
* td
;
1120 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1121 g_free((char *)t
->keys
.array
[pos
]);
1122 td
= (type_descriptor
*)t
->values
.array
[pos
];
1128 void freeTypes(sequence
*t
)
1131 type_descriptor
*tp
;
1133 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1134 tp
= (type_descriptor
*)t
->array
[pos
];
1140 void freeEvents(sequence
*t
)
1145 for(pos
= 0 ; pos
< t
->position
; pos
++) {
1146 ev
= (event_t
*) t
->array
[pos
];
1148 g_free(ev
->description
);
1155 /* Extensible array */
1157 void sequence_init(sequence
*t
)
1161 t
->array
= g_new(void*, t
->size
);
1164 void sequence_dispose(sequence
*t
)
1171 void sequence_push(sequence
*t
, void *elem
)
1175 if(t
->position
>= t
->size
) {
1177 t
->array
= g_new(void*, 2*t
->size
);
1178 memcpy(t
->array
, tmp
, t
->size
* sizeof(void *));
1179 t
->size
= t
->size
* 2;
1182 t
->array
[t
->position
] = elem
;
1186 void *sequence_pop(sequence
*t
)
1188 return t
->array
[t
->position
--];
1192 /* Hash table API, implementation is just linear search for now */
1194 void table_init(table
*t
)
1196 sequence_init(&(t
->keys
));
1197 sequence_init(&(t
->values
));
1200 void table_dispose(table
*t
)
1202 sequence_dispose(&(t
->keys
));
1203 sequence_dispose(&(t
->values
));
1206 void table_insert(table
*t
, char *key
, void *value
)
1208 sequence_push(&(t
->keys
),key
);
1209 sequence_push(&(t
->values
),value
);
1212 void *table_find(table
*t
, char *key
)
1215 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1216 if(g_ascii_strcasecmp((char *)key
,(char *)t
->keys
.array
[pos
]) == 0)
1217 return(t
->values
.array
[pos
]);
1222 void table_insert_int(table
*t
, int *key
, void *value
)
1224 sequence_push(&(t
->keys
),key
);
1225 sequence_push(&(t
->values
),value
);
1228 void *table_find_int(table
*t
, int *key
)
1231 for(pos
= 0 ; pos
< t
->keys
.position
; pos
++) {
1232 if(*key
== *(int *)t
->keys
.array
[pos
])
1233 return(t
->values
.array
[pos
]);
This page took 0.061088 seconds and 4 git commands to generate.