custom
[lttv.git] / ltt / branches / poly / ltt / parser.c
CommitLineData
90395b4b 1/*
0dee0e75 2
3parser.c: Generate helper declarations and functions to trace events
4 from an event description file.
5
6 Copyright (C) 2005, Mathieu Desnoyers
7 Copyright (C) 2002, Xianxiu Yang
8 Copyright (C) 2002, Michel Dagenais
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
90395b4b 22
23/* This program reads the ".xml" event definitions input files
24 and constructs structure for each event.
25
26 The program uses a very simple tokenizer, called from a hand written
27 recursive descent parser to fill a data structure describing the events.
28 The result is a sequence of events definitions which refer to type
29 definitions.
30
31 A table of named types is maintained to allow refering to types by name
32 when the same type is used at several places. Finally a sequence of
33 all types is maintained to facilitate the freeing of all type
34 information when the processing of an ".xml" file is finished. */
35
36#include <stdlib.h>
37#include <string.h>
38#include <stdio.h>
39#include <stdarg.h>
40#include <linux/errno.h>
41#include <assert.h>
a0c1f622 42#include <ctype.h>
90395b4b 43
44#include "parser.h"
45
46
f104d082 47char *intOutputTypes[] = {
48 "int8_t", "int16_t", "int32_t", "int64_t" };
a0c1f622 49
f104d082 50char *uintOutputTypes[] = {
51 "uint8_t", "uint16_t", "uint32_t", "uint64_t" };
a0c1f622 52
f104d082 53char *floatOutputTypes[] = {
54 "undef", "undef", "float", "double" };
a0c1f622 55
56
57
58
90395b4b 59/* helper function */
60void strupper(char *string)
61{
62 char *ptr = string;
63
64 while(*ptr != '\0') {
65 *ptr = toupper(*ptr);
66 ptr++;
67 }
68}
69
70
f104d082 71int getSizeindex(unsigned int value)
90395b4b 72{
73 switch(value) {
74 case 1:
75 return 0;
76 case 2:
77 return 1;
78 case 4:
79 return 2;
80 case 8:
81 return 3;
82 default:
83 printf("Error : unknown value size %d\n", value);
84 exit(-1);
85 }
86}
87
88/*****************************************************************************
89 *Function name
90 * getSize : translate from string to integer
91 *Input params
92 * in : input file handle
93 *Return values
94 * size
95 *****************************************************************************/
96
f104d082 97unsigned long long int getSize(parse_file_t *in)
90395b4b 98{
01e5c8ac 99 char *token, *token2;
83e160f2 100 unsigned long long int ret;
90395b4b 101
102 token = getToken(in);
01e5c8ac 103
104
105 if(in->type == QUOTEDSTRING) {
106 in->type = NUMBER;
107 token2 = token;
108 do {
109 if (!isdigit(*token2)) {
110 in->type = QUOTEDSTRING;
111 break;
112 }
113 } while (*(++token2) != '\0');
114 }
115
90395b4b 116 if(in->type == NUMBER) {
9f2d599d 117 ret = strtoull(token, NULL, 0);
118 } else {
119 goto error;
120 }
9f2d599d 121
122 return ret;
123error:
90395b4b 124 in->error(in,"incorrect size specification");
125 return -1;
126}
127
128/*****************************************************************************
129 *Function name
130 * error_callback : print out error info
131 *Input params
132 * in : input file handle
133 * msg : message to be printed
134 ****************************************************************************/
135
90699b2b 136void error_callback(parse_file_t *in, char *msg)
90395b4b 137{
138 if(in)
139 printf("Error in file %s, line %d: %s\n", in->name, in->lineno, msg);
140 else
141 printf("%s\n",msg);
142 assert(0);
143 exit(1);
144}
145
146/*****************************************************************************
147 *Function name
148 * memAlloc : allocate memory
149 *Input params
150 * size : required memory size
151 *return value
152 * void * : pointer to allocate memory or NULL
153 ****************************************************************************/
154
155void * memAlloc(int size)
156{
157 void * addr;
158 if(size == 0) return NULL;
159 addr = malloc(size);
160 if(!addr){
161 printf("Failed to allocate memory");
162 exit(1);
163 }
164 return addr;
165}
166
167/*****************************************************************************
168 *Function name
169 * allocAndCopy : allocate memory and initialize it
170 *Input params
171 * str : string to be put in memory
172 *return value
173 * char * : pointer to allocate memory or NULL
174 ****************************************************************************/
175
176char *allocAndCopy(char *str)
177{
178 char * addr;
179 if(str == NULL) return NULL;
180 addr = (char *)memAlloc(strlen(str)+1);
181 strcpy(addr,str);
182 return addr;
183}
184
185/**************************************************************************
186 * Function :
187 * getTypeAttributes
188 * Description :
189 * Read the attribute from the input file.
190 *
191 * Parameters :
192 * in , input file handle.
193 * t , the type descriptor to fill.
194 *
195 **************************************************************************/
196
f104d082 197void getTypeAttributes(parse_file_t *in, type_descriptor_t *t,
198 sequence_t * unnamed_types, table_t * named_types)
90395b4b 199{
200 char * token;
83e160f2 201 int car;
90395b4b 202
203 t->fmt = NULL;
f104d082 204 t->size = 0;
7df766d3 205 t->custom_write = 0;
f0b795e0 206 t->network = 0;
90395b4b 207
208 while(1) {
209 token = getToken(in);
210 if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
211 ungetToken(in);
212 break;
213 }
214
215 if(!strcmp("format",token)) {
216 getEqual(in);
217 t->fmt = allocAndCopy(getQuotedString(in));
218 //} else if(!strcmp("name",token)) {
219 // getEqual(in);
220 // car = seekNextChar(in);
221 // if(car == EOF) in->error(in,"name was expected");
222 // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
223 // else t->type_name = allocAndCopy(getName(in));
224 } else if(!strcmp("size",token)) {
225 getEqual(in);
226 t->size = getSize(in);
7df766d3 227 } else if(!strcmp("custom_write", token)) {
228 t->custom_write = 1;
01e5c8ac 229 } else if(!strcmp("byte_order",token)) {
230 getEqual(in);
231 car = seekNextChar(in);
232 if(car == EOF) in->error(in,"byte order was expected (network?)");
233 else if(car == '\"') token = getQuotedString(in);
234 else token = getName(in);
235 if(!strcmp("network", token)) {
236 t->network = 1;
237 }
238 } else if(!strcmp("write",token)) {
239 getEqual(in);
240 car = seekNextChar(in);
241 if(car == EOF) in->error(in,"write type was expected (custom?)");
242 else if(car == '\"') token = getQuotedString(in);
243 else token = getName(in);
244 if(!strcmp("custom", token)) {
245 t->custom_write = 1;
246 }
247 }
248 }
90395b4b 249}
250
251/**************************************************************************
252 * Function :
253 * getEventAttributes
254 * Description :
255 * Read the attribute from the input file.
256 *
257 * Parameters :
258 * in , input file handle.
259 * ev , the event to fill.
260 *
261 **************************************************************************/
262
90699b2b 263void getEventAttributes(parse_file_t *in, event_t *ev)
90395b4b 264{
265 char * token;
83e160f2 266 int car;
90395b4b 267
268 ev->name = NULL;
269 ev->per_trace = 0;
270 ev->per_tracefile = 0;
f5c61f8d 271 ev->param_buffer = 0;
54be3e47 272 ev->no_instrument_function = 0;
90395b4b 273
274 while(1) {
275 token = getToken(in);
276 if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
277 ungetToken(in);
278 break;
279 }
280
281 if(!strcmp("name",token)) {
282 getEqual(in);
283 car = seekNextChar(in);
284 if(car == EOF) in->error(in,"name was expected");
285 else if(car == '\"') ev->name = allocAndCopy(getQuotedString(in));
286 else ev->name = allocAndCopy(getName(in));
01e5c8ac 287 } else if(!strcmp("scope", token)) {
288 getEqual(in);
289 car = seekNextChar(in);
290 if(car == EOF) in->error(in,"scope was expected");
291 else if(car == '\"') token = getQuotedString(in);
292 else token = getName(in);
293 if(!strcmp(token, "trace")) ev->per_trace = 1;
294 else if(!strcmp(token, "tracefile")) ev->per_tracefile = 1;
295 } else if(!strcmp("param", token)) {
296 getEqual(in);
297 car = seekNextChar(in);
298 if(car == EOF) in->error(in,"parameter type was expected");
299 else if(car == '\"') token = getQuotedString(in);
300 else token = getName(in);
301 if(!strcmp(token, "buffer")) ev->param_buffer = 1;
302 } else if(!strcmp("attribute", token)) {
303 getEqual(in);
304 car = seekNextChar(in);
305 if(car == EOF) in->error(in,"attribute was expected");
306 else if(car == '\"') token = getQuotedString(in);
307 else token = getName(in);
308 if(!strcmp(token, "no_instrument_function"))
309 ev->no_instrument_function = 1;
310 }
90395b4b 311 }
312}
313
314/**************************************************************************
315 * Function :
316 * getFacilityAttributes
317 * Description :
318 * Read the attribute from the input file.
319 *
320 * Parameters :
321 * in , input file handle.
322 * fac , the facility to fill.
323 *
324 **************************************************************************/
325
90699b2b 326void getFacilityAttributes(parse_file_t *in, facility_t *fac)
90395b4b 327{
328 char * token;
83e160f2 329 int car;
90395b4b 330
331 fac->name = NULL;
f5d7967f 332 fac->arch = NULL;
383d64da 333 fac->user = 0;
90395b4b 334
335 while(1) {
336 token = getToken(in);
337 if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
338 ungetToken(in);
339 break;
340 }
341
342 if(!strcmp("name",token)) {
343 getEqual(in);
344 car = seekNextChar(in);
345 if(car == EOF) in->error(in,"name was expected");
346 else if(car == '\"') fac->name = allocAndCopy(getQuotedString(in));
347 else fac->name = allocAndCopy(getName(in));
01e5c8ac 348 if(!strncmp(fac->name, "user_", sizeof("user_")-1))
383d64da 349 fac->user = 1;
f5d7967f 350 } else if(!strcmp("arch", token)) {
351 getEqual(in);
352 car = seekNextChar(in);
01e5c8ac 353 if(car == '\"') fac->arch = allocAndCopy(getQuotedString(in));
f5d7967f 354 else fac->arch = allocAndCopy(getName(in));
355 }
90395b4b 356 }
357}
358
359/**************************************************************************
360 * Function :
361 * getFieldAttributes
362 * Description :
363 * Read the attribute from the input file.
364 *
365 * Parameters :
366 * in , input file handle.
367 * f , the field to fill.
368 *
369 **************************************************************************/
370
90699b2b 371void getFieldAttributes(parse_file_t *in, field_t *f)
90395b4b 372{
373 char * token;
83e160f2 374 int car;
90395b4b 375
376 f->name = NULL;
377
378 while(1) {
379 token = getToken(in);
380 if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
381 ungetToken(in);
382 break;
383 }
384
385 if(!strcmp("name",token)) {
386 getEqual(in);
387 car = seekNextChar(in);
388 if(car == EOF) in->error(in,"name was expected");
389 else if(car == '\"') f->name = allocAndCopy(getQuotedString(in));
390 else f->name = allocAndCopy(getName(in));
391 }
f0b795e0 392 }
90395b4b 393}
394
90699b2b 395char *getNameAttribute(parse_file_t *in)
90395b4b 396{
397 char * token;
398 char *name = NULL;
83e160f2 399 int car;
90395b4b 400
401 while(1) {
402 token = getToken(in);
90395b4b 403 if(!strcmp("name",token)) {
404 getEqual(in);
405 car = seekNextChar(in);
406 if(car == EOF) in->error(in,"name was expected");
407 else if(car == '\"') name = allocAndCopy(getQuotedString(in));
408 else name = allocAndCopy(getName(in));
0dee0e75 409 } else {
410 ungetToken(in);
411 break;
90395b4b 412 }
0dee0e75 413
90395b4b 414 }
415 if(name == NULL) in->error(in, "Name was expected");
416 return name;
90395b4b 417}
418
419
420
01e5c8ac 421//for <label name=label_name value=n format="...">, value is an option
9f2d599d 422//Return value : 0 : no value, 1 : has a value
423int getValueAttribute(parse_file_t *in, long long *value)
90395b4b 424{
01e5c8ac 425 char * token, *token2;
90395b4b 426
01e5c8ac 427 token = getToken(in);
428
429 if(strcmp("/",token) == 0 || strcmp(">", token) == 0){
90395b4b 430 ungetToken(in);
9f2d599d 431 return 0;
90395b4b 432 }
90395b4b 433 if(strcmp("value",token))in->error(in,"value was expected");
01e5c8ac 434
90395b4b 435 getEqual(in);
436 token = getToken(in);
9f2d599d 437
01e5c8ac 438 if(in->type == QUOTEDSTRING) {
439 in->type = NUMBER;
440 token2 = token;
441 do {
442 if (!isdigit(*token2)) {
443 in->type = QUOTEDSTRING;
444 break;
445 }
446 } while (*(++token2) != '\0');
447 }
448
449 if(in->type == NUMBER)
9f2d599d 450 *value = strtoll(token, NULL, 0);
01e5c8ac 451 else
9f2d599d 452 goto error;
9f2d599d 453 return 1;
9f2d599d 454error:
455 in->error(in,"incorrect size specification");
456 return 0;
90395b4b 457}
458
90699b2b 459char * getDescription(parse_file_t *in)
90395b4b 460{
461 long int pos;
83e160f2 462 char * token, *str;
463 int car;
90395b4b 464
465 pos = ftell(in->fp);
466
467 getLAnglebracket(in);
468 token = getName(in);
469 if(strcmp("description",token)){
470 fseek(in->fp, pos, SEEK_SET);
471 return NULL;
472 }
473
474 getRAnglebracket(in);
475
476 pos = 0;
477 while((car = getc(in->fp)) != EOF) {
478 if(car == '<') break;
479 if(car == '\0') continue;
480 in->buffer[pos] = car;
481 pos++;
482 }
483 if(car == EOF)in->error(in,"not a valid description");
484 in->buffer[pos] = '\0';
485
486 str = allocAndCopy(in->buffer);
487
488 getForwardslash(in);
489 token = getName(in);
490 if(strcmp("description", token))in->error(in,"not a valid description");
491 getRAnglebracket(in);
492
493 return str;
494}
495
496/*****************************************************************************
497 *Function name
498 * parseFacility : generate event list
499 *Input params
500 * in : input file handle
501 * fac : empty facility
502 *Output params
503 * fac : facility filled with event list
504 ****************************************************************************/
505
90699b2b 506void parseFacility(parse_file_t *in, facility_t * fac)
90395b4b 507{
508 char * token;
90699b2b 509 event_t *ev;
90395b4b 510
511 getFacilityAttributes(in, fac);
512 if(fac->name == NULL) in->error(in, "Attribute not named");
f5d7967f 513
90395b4b 514 fac->capname = allocAndCopy(fac->name);
515 strupper(fac->capname);
516 getRAnglebracket(in);
517
518 fac->description = getDescription(in);
519
520 while(1){
521 getLAnglebracket(in);
522
523 token = getToken(in);
524 if(in->type == ENDFILE)
525 in->error(in,"the definition of the facility is not finished");
526
527 if(strcmp("event",token) == 0){
90699b2b 528 ev = (event_t*) memAlloc(sizeof(event_t));
90395b4b 529 sequence_push(&(fac->events),ev);
530 parseEvent(in,ev, &(fac->unnamed_types), &(fac->named_types));
531 }else if(strcmp("type",token) == 0){
532 parseTypeDefinition(in, &(fac->unnamed_types), &(fac->named_types));
533 }else if(in->type == FORWARDSLASH){
534 break;
535 }else in->error(in,"event or type token expected\n");
536 }
537
538 token = getName(in);
539 if(strcmp("facility",token)) in->error(in,"not the end of the facility");
540 getRAnglebracket(in); //</facility>
541}
542
543/*****************************************************************************
544 *Function name
545 * parseEvent : generate event from event definition
546 *Input params
547 * in : input file handle
548 * ev : new event
549 * unnamed_types : array of unamed types
550 * named_types : array of named types
551 *Output params
552 * ev : new event (parameters are passed to it)
553 ****************************************************************************/
554
90699b2b 555void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types,
556 table_t * named_types)
90395b4b 557{
558 char *token;
f104d082 559 field_t *f;
90395b4b 560
f104d082 561 sequence_init(&(ev->fields));
90395b4b 562 //<event name=eventtype_name>
563 getEventAttributes(in, ev);
564 if(ev->name == NULL) in->error(in, "Event not named");
565 getRAnglebracket(in);
566
f104d082 567 //<description>...</description>
90395b4b 568 ev->description = getDescription(in);
569
f104d082 570 int got_end = 0;
571 /* Events can have multiple fields. each field form at least a function
572 * parameter of the logging function. */
573 while(!got_end) {
574 getLAnglebracket(in);
575 token = getToken(in);
576
577 switch(in->type) {
578 case FORWARDSLASH: /* </event> */
579 token = getName(in);
580 if(strcmp("event",token))in->error(in,"not an event definition");
581 getRAnglebracket(in); //</event>
582 got_end = 1;
583 break;
584 case NAME: /* a field */
585 if(strcmp("field",token))in->error(in,"expecting a field");
586 f = (field_t *)memAlloc(sizeof(field_t));
587 sequence_push(&(ev->fields),f);
588 parseFields(in, f, unnamed_types, named_types, 1);
589 break;
590 default:
591 in->error(in, "expecting </event> or <field >");
592 break;
593 }
594 }
595#if 0
596 if(in->type == FORWARDSLASH){ //</event> NOTHING
597 ev->type = NULL;
598 }else if(in->type == NAME){
599 if(strcmp("struct",token)==0 || strcmp("typeref",token)==0){
600 ungetToken(in);
601 ev->type = parseType(in,NULL, unnamed_types, named_types);
602 if(ev->type->type != STRUCT && ev->type->type != NONE)
603 in->error(in,"type must be a struct");
604 }else in->error(in, "not a valid type");
605
606 getLAnglebracket(in);
607 getForwardslash(in);
608 }else in->error(in,"not a struct type");
609 getLAnglebracket(in);
610 getForwardslash(in);
611 token = getName(in);
612 if(strcmp("event",token))in->error(in,"not an event definition");
613 getRAnglebracket(in); //</event>
614#endif //0
90395b4b 615}
616
617/*****************************************************************************
618 *Function name
619 * parseField : get field infomation from buffer
620 *Input params
621 * in : input file handle
f104d082 622 * f : field
90395b4b 623 * unnamed_types : array of unamed types
624 * named_types : array of named types
f104d082 625 * tag : is field surrounded by a <field> </field> tag ?
90395b4b 626 ****************************************************************************/
627
f104d082 628void parseFields(parse_file_t *in, field_t *f,
90699b2b 629 sequence_t * unnamed_types,
f104d082 630 table_t * named_types,
631 int tag)
90395b4b 632{
633 char * token;
f104d082 634 if(tag) {
635 //<field name=field_name> <description> <type> </field>
636 getFieldAttributes(in, f);
637 if(f->name == NULL) in->error(in, "Field not named");
638 getRAnglebracket(in);
90395b4b 639
f104d082 640 f->description = getDescription(in);
15244807 641 } else {
642 f->description = NULL;
f104d082 643 }
90395b4b 644
645 //<int size=...>
646 getLAnglebracket(in);
647 f->type = parseType(in,NULL, unnamed_types, named_types);
648
f104d082 649 if(tag) {
650 getLAnglebracket(in);
651 getForwardslash(in);
652 token = getName(in);
653 if(strcmp("field",token))in->error(in,"not a valid field definition");
654 getRAnglebracket(in); //</field>
655 }
90395b4b 656}
657
658
659/*****************************************************************************
660 *Function name
661 * parseType : get type information, type can be :
662 * Primitive:
663 * int(size,fmt); uint(size,fmt); float(size,fmt);
664 * string(fmt); enum(size,fmt,(label1,label2...))
665 * Compound:
666 * array(arraySize, type); sequence(lengthSize,type)
667 * struct(field(name,type,description)...)
668 * type name:
669 * type(name,type)
670 *Input params
671 * in : input file handle
672 * inType : a type descriptor
673 * unnamed_types : array of unamed types
674 * named_types : array of named types
675 *Return values
676 * type_descriptor* : a type descriptor
677 ****************************************************************************/
678
90699b2b 679type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
680 sequence_t * unnamed_types, table_t * named_types)
90395b4b 681{
682 char *token;
90699b2b 683 type_descriptor_t *t;
f104d082 684 field_t *f;
90395b4b 685
686 if(inType == NULL) {
90699b2b 687 t = (type_descriptor_t *) memAlloc(sizeof(type_descriptor_t));
90395b4b 688 t->type_name = NULL;
689 t->type = NONE;
690 t->fmt = NULL;
691 sequence_push(unnamed_types,t);
692 }
693 else t = inType;
694
695 token = getName(in);
696
697 if(strcmp(token,"struct") == 0) {
698 t->type = STRUCT;
f104d082 699 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 700 getRAnglebracket(in); //<struct>
701 getLAnglebracket(in); //<field name=..>
702 token = getToken(in);
703 sequence_init(&(t->fields));
704 while(strcmp("field",token) == 0){
f104d082 705 f = (field_t *)memAlloc(sizeof(field_t));
706 sequence_push(&(t->fields),f);
707
708 parseFields(in, f, unnamed_types, named_types, 1);
90395b4b 709
710 //next field
711 getLAnglebracket(in);
712 token = getToken(in);
713 }
714 if(strcmp("/",token))in->error(in,"not a valid structure definition");
715 token = getName(in);
716 if(strcmp("struct",token)!=0)
717 in->error(in,"not a valid structure definition");
718 getRAnglebracket(in); //</struct>
719 }
720 else if(strcmp(token,"union") == 0) {
721 t->type = UNION;
f104d082 722 getTypeAttributes(in, t, unnamed_types, named_types);
723 getRAnglebracket(in); //<union>
90395b4b 724
725 getLAnglebracket(in); //<field name=..>
726 token = getToken(in);
727 sequence_init(&(t->fields));
728 while(strcmp("field",token) == 0){
f104d082 729 f = (field_t *)memAlloc(sizeof(field_t));
730 sequence_push(&(t->fields),f);
731 parseFields(in, f, unnamed_types, named_types, 1);
90395b4b 732
733 //next field
734 getLAnglebracket(in);
735 token = getToken(in);
736 }
737 if(strcmp("/",token))in->error(in,"not a valid union definition");
738 token = getName(in);
739 if(strcmp("union",token)!=0)
740 in->error(in,"not a valid union definition");
741 getRAnglebracket(in); //</union>
742 }
743 else if(strcmp(token,"array") == 0) {
744 t->type = ARRAY;
f104d082 745 sequence_init(&(t->fields));
746 getTypeAttributes(in, t, unnamed_types, named_types);
747 if(t->size == 0) in->error(in, "Array has empty size");
748 getForwardslash(in);
90395b4b 749 getRAnglebracket(in); //<array size=n>
750
f104d082 751 //getLAnglebracket(in); //<subtype>
752 /* subfield */
753 f = (field_t *)memAlloc(sizeof(field_t));
754 sequence_push(&(t->fields),f);
755 parseFields(in, f, unnamed_types, named_types, 0);
756
757 //getLAnglebracket(in); //<type struct>
758 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
90395b4b 759
760 getLAnglebracket(in); //</array>
761 getForwardslash(in);
762 token = getName(in);
763 if(strcmp("array",token))in->error(in,"not a valid array definition");
764 getRAnglebracket(in); //</array>
765 }
766 else if(strcmp(token,"sequence") == 0) {
767 t->type = SEQUENCE;
f104d082 768 sequence_init(&(t->fields));
7df766d3 769 getTypeAttributes(in, t, unnamed_types, named_types);
770 getForwardslash(in);
f104d082 771 getRAnglebracket(in); //<sequence>
772
773 //getLAnglebracket(in); //<sequence size type>
774 /* subfield */
775 f = (field_t *)memAlloc(sizeof(field_t));
776 sequence_push(&(t->fields),f);
777 parseFields(in, f, unnamed_types, named_types, 0);
778
779 //getLAnglebracket(in); //<subtype>
780 /* subfield */
781 f = (field_t *)memAlloc(sizeof(field_t));
782 sequence_push(&(t->fields),f);
783 parseFields(in, f, unnamed_types, named_types, 0);
784
785 //getLAnglebracket(in); //<type sequence>
786 //t->length_type = parseType(in, NULL, unnamed_types, named_types);
787
788 //getLAnglebracket(in); //<type sequence>
789
790 //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
791
792 if(t->fields.position < 1) in->error(in, "Sequence has no length type");
793 if(t->fields.position < 2) in->error(in, "Sequence has no subtype");
794 switch(((field_t*)t->fields.array[0])->type->type) {
795 case UINT_FIXED :
796 case UCHAR :
797 case USHORT :
798 case UINT :
799 case ULONG :
800 case SIZE_T :
801 case OFF_T :
802 break;
803 default:
804 in->error(in, "Wrong length type for sequence");
805 }
90395b4b 806
807 getLAnglebracket(in); //</sequence>
808 getForwardslash(in);
809 token = getName(in);
810 if(strcmp("sequence",token))in->error(in,"not a valid sequence definition");
811 getRAnglebracket(in); //</sequence>
812 }
813 else if(strcmp(token,"enum") == 0) {
f104d082 814 char * str;
9f2d599d 815 long long value = -1;
f104d082 816
90395b4b 817 t->type = ENUM;
818 sequence_init(&(t->labels));
f104d082 819 sequence_init(&(t->labels_values));
90395b4b 820 sequence_init(&(t->labels_description));
821 t->already_printed = 0;
f104d082 822 getTypeAttributes(in, t, unnamed_types, named_types);
823 //if(t->size == 0) in->error(in, "Sequence has empty size");
824 //Mathieu : we fix enum size to target int size. GCC is always like this.
825 //fox copy optimisation.
826 if(t->size != 0) in->error(in, "Enum has fixed size of target int.");
827 t->size = 0;
90395b4b 828 getRAnglebracket(in);
829
830 //<label name=label1 value=n/>
831 getLAnglebracket(in);
832 token = getToken(in); //"label" or "/"
833 while(strcmp("label",token) == 0){
f104d082 834 int *label_value = malloc(sizeof(int));
9f2d599d 835 int has_value = 0;
836 long long loc_value;
f104d082 837
7b143580 838 str = allocAndCopy(getNameAttribute(in));
9f2d599d 839 has_value = getValueAttribute(in, &loc_value);
f104d082 840
841 sequence_push(&(t->labels),str);
842
9f2d599d 843 if(has_value) value = loc_value;
f104d082 844 else value++;
845
846 *label_value = value;
847 sequence_push(&(t->labels_values), label_value);
90395b4b 848
849 getForwardslash(in);
850 getRAnglebracket(in);
851
852 //read description if any. May be NULL.
853 str = allocAndCopy(getDescription(in));
854 sequence_push(&(t->labels_description),str);
855
856 //next label definition
857 getLAnglebracket(in);
858 token = getToken(in); //"label" or "/"
859 }
860 if(strcmp("/",token))in->error(in, "not a valid enum definition");
861 token = getName(in);
862 if(strcmp("enum",token))in->error(in, "not a valid enum definition");
863 getRAnglebracket(in); //</label>
864 }
f104d082 865 else if(strcmp(token,"int_fixed") == 0) {
866 t->type = INT_FIXED;
867 getTypeAttributes(in, t, unnamed_types, named_types);
868 if(t->size == 0) in->error(in, "int has empty size");
869 getForwardslash(in);
870 getRAnglebracket(in);
871 }
872 else if(strcmp(token,"uint_fixed") == 0) {
873 t->type = UINT_FIXED;
874 getTypeAttributes(in, t, unnamed_types, named_types);
875 if(t->size == 0) in->error(in, "uint has empty size");
876 getForwardslash(in);
877 getRAnglebracket(in);
878 }
879 else if(strcmp(token,"char") == 0) {
880 t->type = CHAR;
f104d082 881 getTypeAttributes(in, t, unnamed_types, named_types);
743e50fd 882 t->size = 1;
f104d082 883 getForwardslash(in);
884 getRAnglebracket(in);
885 }
886 else if(strcmp(token,"uchar") == 0) {
887 t->type = UCHAR;
f104d082 888 getTypeAttributes(in, t, unnamed_types, named_types);
743e50fd 889 t->size = 1;
f104d082 890 getForwardslash(in);
891 getRAnglebracket(in);
892 }
893 else if(strcmp(token,"short") == 0) {
894 t->type = SHORT;
f104d082 895 getTypeAttributes(in, t, unnamed_types, named_types);
743e50fd 896 t->size = 2;
f104d082 897 getForwardslash(in);
898 getRAnglebracket(in);
899 }
900 else if(strcmp(token,"ushort") == 0) {
901 t->type = USHORT;
f104d082 902 getTypeAttributes(in, t, unnamed_types, named_types);
743e50fd 903 t->size = 2;
f104d082 904 getForwardslash(in);
905 getRAnglebracket(in);
906 }
90395b4b 907 else if(strcmp(token,"int") == 0) {
908 t->type = INT;
f104d082 909 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 910 getForwardslash(in);
911 getRAnglebracket(in);
912 }
913 else if(strcmp(token,"uint") == 0) {
914 t->type = UINT;
f104d082 915 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 916 getForwardslash(in);
917 getRAnglebracket(in);
918 }
f104d082 919
90395b4b 920 else if(strcmp(token,"pointer") == 0) {
921 t->type = POINTER;
f104d082 922 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 923 getForwardslash(in);
924 getRAnglebracket(in);
925 }
926 else if(strcmp(token,"long") == 0) {
927 t->type = LONG;
f104d082 928 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 929 getForwardslash(in);
930 getRAnglebracket(in);
931 }
932 else if(strcmp(token,"ulong") == 0) {
933 t->type = ULONG;
f104d082 934 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 935 getForwardslash(in);
936 getRAnglebracket(in);
937 }
938 else if(strcmp(token,"size_t") == 0) {
939 t->type = SIZE_T;
f104d082 940 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 941 getForwardslash(in);
942 getRAnglebracket(in);
943 }
944 else if(strcmp(token,"ssize_t") == 0) {
945 t->type = SSIZE_T;
f104d082 946 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 947 getForwardslash(in);
948 getRAnglebracket(in);
949 }
950 else if(strcmp(token,"off_t") == 0) {
951 t->type = OFF_T;
f104d082 952 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 953 getForwardslash(in);
954 getRAnglebracket(in);
955 }
956 else if(strcmp(token,"float") == 0) {
957 t->type = FLOAT;
f104d082 958 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 959 getForwardslash(in);
960 getRAnglebracket(in);
961 }
962 else if(strcmp(token,"string") == 0) {
963 t->type = STRING;
f104d082 964 getTypeAttributes(in, t, unnamed_types, named_types);
90395b4b 965 getForwardslash(in);
966 getRAnglebracket(in);
967 }
968 else if(strcmp(token,"typeref") == 0){
969 // Must be a named type
f104d082 970 free(t);
971 sequence_pop(unnamed_types);
972 token = getNameAttribute(in);
973 t = find_named_type(token, named_types);
974 if(t == NULL) in->error(in,"Named referred to must be pre-declared.");
975 getForwardslash(in); //<typeref name=type_name/>
976 getRAnglebracket(in);
977 return t;
90395b4b 978 }else in->error(in,"not a valid type");
979
980 return t;
981}
982
983/*****************************************************************************
984 *Function name
985 * find_named_type : find a named type from hash table
986 *Input params
987 * name : type name
988 * named_types : array of named types
989 *Return values
990 * type_descriptor * : a type descriptor
991 *****************************************************************************/
992
90699b2b 993type_descriptor_t * find_named_type(char *name, table_t * named_types)
90395b4b 994{
90699b2b 995 type_descriptor_t *t;
90395b4b 996
997 t = table_find(named_types,name);
f104d082 998
90395b4b 999 return t;
f104d082 1000}
1001
1002type_descriptor_t * create_named_type(char *name, table_t * named_types)
1003{
1004 type_descriptor_t *t;
1005
1006 t = (type_descriptor_t *)memAlloc(sizeof(type_descriptor_t));
1007 t->type_name = allocAndCopy(name);
1008 t->type = NONE;
1009 t->fmt = NULL;
1010 table_insert(named_types,t->type_name,t);
1011 // table_insert(named_types,allocAndCopy(name),t);
1012 return t;
1013}
90395b4b 1014
1015/*****************************************************************************
1016 *Function name
1017 * parseTypeDefinition : get type information from type definition
1018 *Input params
1019 * in : input file handle
1020 * unnamed_types : array of unamed types
1021 * named_types : array of named types
1022 *****************************************************************************/
1023
90699b2b 1024void parseTypeDefinition(parse_file_t * in, sequence_t * unnamed_types,
1025 table_t * named_types)
90395b4b 1026{
1027 char *token;
90699b2b 1028 type_descriptor_t *t;
90395b4b 1029
1030 token = getNameAttribute(in);
1031 if(token == NULL) in->error(in, "Type has empty name");
f104d082 1032 t = create_named_type(token, named_types);
90395b4b 1033
1034 if(t->type != NONE) in->error(in,"redefinition of named type");
1035 getRAnglebracket(in); //<type name=type_name>
1036 getLAnglebracket(in); //<
1037 token = getName(in);
1038 //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
1039 ungetToken(in);
1040 parseType(in,t, unnamed_types, named_types);
1041
1042 //</type>
1043 getLAnglebracket(in);
1044 getForwardslash(in);
1045 token = getName(in);
1046 if(strcmp("type",token))in->error(in,"not a valid type definition");
1047 getRAnglebracket(in); //</type>
1048}
1049
1050/**************************************************************************
1051 * Function :
1052 * getComa, getName, getNumber, getEqual
1053 * Description :
1054 * Read a token from the input file, check its type, return it scontent.
1055 *
1056 * Parameters :
1057 * in , input file handle.
1058 *
1059 * Return values :
1060 * address of token content.
1061 *
1062 **************************************************************************/
1063
90699b2b 1064char *getName(parse_file_t * in)
90395b4b 1065{
1066 char *token;
1067
1068 token = getToken(in);
7b143580 1069 // Optional descriptions
1070 // if(in->type != NAME) in->error(in,"Name token was expected");
90395b4b 1071 return token;
1072}
1073
90699b2b 1074int getNumber(parse_file_t * in)
90395b4b 1075{
1076 char *token;
1077
1078 token = getToken(in);
1079 if(in->type != NUMBER) in->error(in, "Number token was expected");
1080 return atoi(token);
1081}
1082
90699b2b 1083char *getForwardslash(parse_file_t * in)
90395b4b 1084{
1085 char *token;
1086
1087 token = getToken(in);
f104d082 1088 //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
1089 /* Mathieu : final / is optional now. */
1090 if(in->type != FORWARDSLASH) ungetToken(in);
1091
90395b4b 1092 return token;
1093}
1094
90699b2b 1095char *getLAnglebracket(parse_file_t * in)
90395b4b 1096{
1097 char *token;
1098
1099 token = getToken(in);
1100 if(in->type != LANGLEBRACKET) in->error(in, "Left angle bracket was expected");
1101 return token;
1102}
1103
90699b2b 1104char *getRAnglebracket(parse_file_t * in)
90395b4b 1105{
1106 char *token;
1107
1108 token = getToken(in);
1109 if(in->type != RANGLEBRACKET) in->error(in, "Right angle bracket was expected");
1110 return token;
1111}
1112
90699b2b 1113char *getQuotedString(parse_file_t * in)
90395b4b 1114{
1115 char *token;
1116
1117 token = getToken(in);
1118 if(in->type != QUOTEDSTRING) in->error(in, "quoted string was expected");
1119 return token;
1120}
1121
90699b2b 1122char * getEqual(parse_file_t *in)
90395b4b 1123{
1124 char *token;
1125
1126 token = getToken(in);
1127 if(in->type != EQUAL) in->error(in, "equal was expected");
1128 return token;
1129}
1130
83e160f2 1131int seekNextChar(parse_file_t *in)
90395b4b 1132{
83e160f2 1133 int car;
90395b4b 1134 while((car = getc(in->fp)) != EOF) {
1135 if(!isspace(car)){
1136 ungetc(car,in->fp);
1137 return car;
1138 }
1139 }
1140 return EOF;
1141}
1142
1143/******************************************************************
1144 * Function :
1145 * getToken, ungetToken
1146 * Description :
1147 * Read a token from the input file and return its type and content.
1148 * Line numbers are accounted for and whitespace/comments are skipped.
1149 *
1150 * Parameters :
1151 * in, input file handle.
1152 *
1153 * Return values :
1154 * address of token content.
1155 *
1156 ******************************************************************/
1157
90699b2b 1158void ungetToken(parse_file_t * in)
90395b4b 1159{
1160 in->unget = 1;
1161}
1162
90699b2b 1163char *getToken(parse_file_t * in)
90395b4b 1164{
1165 FILE *fp = in->fp;
83e160f2 1166 int car, car1;
90395b4b 1167 int pos = 0, escaped;
1168
1169 if(in->unget == 1) {
1170 in->unget = 0;
1171 return in->buffer;
1172 }
1173
1174 /* skip whitespace and comments */
1175
1176 while((car = getc(fp)) != EOF) {
1177 if(car == '/') {
1178 car1 = getc(fp);
1179 if(car1 == '*') skipComment(in);
1180 else if(car1 == '/') skipEOL(in);
1181 else {
1182 car1 = ungetc(car1,fp);
1183 break;
1184 }
1185 }
1186 else if(car == '\n') in->lineno++;
1187 else if(!isspace(car)) break;
1188 }
1189
1190 switch(car) {
1191 case EOF:
1192 in->type = ENDFILE;
1193 break;
1194 case '/':
1195 in->type = FORWARDSLASH;
1196 in->buffer[pos] = car;
1197 pos++;
1198 break;
1199 case '<':
1200 in->type = LANGLEBRACKET;
1201 in->buffer[pos] = car;
1202 pos++;
1203 break;
1204 case '>':
1205 in->type = RANGLEBRACKET;
1206 in->buffer[pos] = car;
1207 pos++;
1208 break;
1209 case '=':
1210 in->type = EQUAL;
1211 in->buffer[pos] = car;
1212 pos++;
1213 break;
1214 case '"':
1215 escaped = 0;
1216 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
1217 if(car == '\\' && escaped == 0) {
01e5c8ac 1218 in->buffer[pos] = car;
1219 pos++;
90395b4b 1220 escaped = 1;
1221 continue;
1222 }
1223 if(car == '"' && escaped == 0) break;
1224 if(car == '\n' && escaped == 0) {
1225 in->error(in, "non escaped newline inside quoted string");
1226 }
1227 if(car == '\n') in->lineno++;
1228 in->buffer[pos] = car;
1229 pos++;
1230 escaped = 0;
1231 }
1232 if(car == EOF) in->error(in,"no ending quotemark");
1233 if(pos == BUFFER_SIZE) in->error(in, "quoted string token too large");
1234 in->type = QUOTEDSTRING;
1235 break;
1236 default:
1237 if(isdigit(car)) {
1238 in->buffer[pos] = car;
1239 pos++;
1240 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
1241 if(!isdigit(car)) {
1242 ungetc(car,fp);
1243 break;
1244 }
1245 in->buffer[pos] = car;
1246 pos++;
1247 }
01e5c8ac 1248 if(car == EOF) ungetc(car,fp);
90395b4b 1249 if(pos == BUFFER_SIZE) in->error(in, "number token too large");
1250 in->type = NUMBER;
01e5c8ac 1251 }
7b143580 1252 else if(isalnum(car) || car == '_' || car == '-') {
90395b4b 1253 in->buffer[0] = car;
1254 pos = 1;
1255 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
7b143580 1256 if(!(isalnum(car) || car == '_' || car == '-')) {
90395b4b 1257 ungetc(car,fp);
1258 break;
1259 }
1260 in->buffer[pos] = car;
1261 pos++;
1262 }
01e5c8ac 1263 if(car == EOF) ungetc(car,fp);
90395b4b 1264 if(pos == BUFFER_SIZE) in->error(in, "name token too large");
1265 in->type = NAME;
01e5c8ac 1266 } else if(car == '?') {
1267 in->buffer[0] = car;
1268 pos++;
1269 }
90395b4b 1270 else in->error(in, "invalid character, unrecognized token");
1271 }
1272 in->buffer[pos] = 0;
1273 return in->buffer;
1274}
1275
90699b2b 1276void skipComment(parse_file_t * in)
90395b4b 1277{
83e160f2 1278 int car;
90395b4b 1279 while((car = getc(in->fp)) != EOF) {
1280 if(car == '\n') in->lineno++;
1281 else if(car == '*') {
1282 car = getc(in->fp);
1283 if(car ==EOF) break;
1284 if(car == '/') return;
1285 ungetc(car,in->fp);
1286 }
1287 }
1288 if(car == EOF) in->error(in,"comment begining with '/*' has no ending '*/'");
1289}
1290
90699b2b 1291void skipEOL(parse_file_t * in)
90395b4b 1292{
83e160f2 1293 int car;
90395b4b 1294 while((car = getc(in->fp)) != EOF) {
1295 if(car == '\n') {
1296 ungetc(car,in->fp);
1297 break;
1298 }
1299 }
1300 if(car == EOF)ungetc(car, in->fp);
1301}
1302
1303/*****************************************************************************
1304 *Function name
1305 * checkNamedTypesImplemented : check if all named types have definition
1306 ****************************************************************************/
1307
90699b2b 1308void checkNamedTypesImplemented(table_t * named_types)
90395b4b 1309{
90699b2b 1310 type_descriptor_t *t;
90395b4b 1311 int pos;
1312 char str[256];
1313
1314 for(pos = 0 ; pos < named_types->values.position; pos++) {
90699b2b 1315 t = (type_descriptor_t *) named_types->values.array[pos];
90395b4b 1316 if(t->type == NONE){
90699b2b 1317 sprintf(str,"named type '%s' has no definition",
1318 (char*)named_types->keys.array[pos]);
90395b4b 1319 error_callback(NULL,str);
1320 }
1321 }
1322}
1323
1324
1325/*****************************************************************************
1326 *Function name
1327 * generateChecksum : generate checksum for the facility
1328 *Input Params
1329 * facName : name of facility
1330 *Output Params
1331 * checksum : checksum for the facility
1332 ****************************************************************************/
1333
90699b2b 1334void generateChecksum(char* facName,
f104d082 1335 unsigned int * checksum, sequence_t * events)
90395b4b 1336{
1337 unsigned long crc ;
1338 int pos;
90699b2b 1339 event_t * ev;
2312de30 1340 unsigned int i;
90395b4b 1341
1342 crc = crc32(facName);
1343 for(pos = 0; pos < events->position; pos++){
90699b2b 1344 ev = (event_t *)(events->array[pos]);
f104d082 1345 crc = partial_crc32(ev->name, crc);
2312de30 1346 for(i = 0; i < ev->fields.position; i++) {
f104d082 1347 field_t *f = (field_t*)ev->fields.array[i];
1348 crc = partial_crc32(f->name, crc);
1349 crc = getTypeChecksum(crc, f->type);
1350 }
90395b4b 1351 }
1352 *checksum = crc;
1353}
1354
1355/*****************************************************************************
1356 *Function name
1357 * getTypeChecksum : generate checksum by type info
1358 *Input Params
1359 * crc : checksum generated so far
1360 * type : type descriptor containing type info
1361 *Return value
1362 * unsigned long : checksum
1363 *****************************************************************************/
1364
90699b2b 1365unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type)
90395b4b 1366{
1367 unsigned long crc = aCrc;
1368 char * str = NULL, buf[16];
1369 int flag = 0, pos;
90699b2b 1370 field_t * fld;
90395b4b 1371
1372 switch(type->type){
f104d082 1373 case INT_FIXED:
1374 str = intOutputTypes[getSizeindex(type->size)];
90395b4b 1375 break;
f104d082 1376 case UINT_FIXED:
1377 str = uintOutputTypes[getSizeindex(type->size)];
90395b4b 1378 break;
1379 case POINTER:
1380 str = allocAndCopy("void *");
1381 flag = 1;
1382 break;
f104d082 1383 case CHAR:
1384 str = allocAndCopy("signed char");
1385 flag = 1;
1386 break;
1387 case UCHAR:
1388 str = allocAndCopy("unsigned char");
1389 flag = 1;
1390 break;
1391 case SHORT:
1392 str = allocAndCopy("short");
1393 flag = 1;
1394 break;
1395 case USHORT:
1396 str = allocAndCopy("unsigned short");
1397 flag = 1;
1398 break;
1399 case INT:
1400 str = allocAndCopy("int");
1401 flag = 1;
1402 break;
1403 case UINT:
1404 str = allocAndCopy("uint");
1405 flag = 1;
1406 break;
90395b4b 1407 case LONG:
1408 str = allocAndCopy("long");
1409 flag = 1;
1410 break;
1411 case ULONG:
1412 str = allocAndCopy("unsigned long");
1413 flag = 1;
1414 break;
1415 case SIZE_T:
1416 str = allocAndCopy("size_t");
1417 flag = 1;
1418 break;
1419 case SSIZE_T:
1420 str = allocAndCopy("ssize_t");
1421 flag = 1;
1422 break;
1423 case OFF_T:
1424 str = allocAndCopy("off_t");
1425 flag = 1;
1426 break;
1427 case FLOAT:
f104d082 1428 str = floatOutputTypes[getSizeindex(type->size)];
90395b4b 1429 break;
1430 case STRING:
1431 str = allocAndCopy("string");
1432 flag = 1;
1433 break;
1434 case ENUM:
f104d082 1435 //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]);
1436 str = allocAndCopy("enum");
90395b4b 1437 flag = 1;
1438 break;
1439 case ARRAY:
f104d082 1440 sprintf(buf,"%zu", type->size);
90395b4b 1441 str = appendString("array ",buf);
1442 flag = 1;
1443 break;
1444 case SEQUENCE:
743e50fd 1445 str = allocAndCopy("sequence ");
90395b4b 1446 flag = 1;
1447 break;
1448 case STRUCT:
1449 str = allocAndCopy("struct");
1450 flag = 1;
1451 break;
1452 case UNION:
1453 str = allocAndCopy("union");
1454 flag = 1;
1455 break;
1456 default:
1457 error_callback(NULL, "named type has no definition");
1458 break;
1459 }
1460
1461 crc = partial_crc32(str,crc);
1462 if(flag) free(str);
1463
1464 if(type->fmt) crc = partial_crc32(type->fmt,crc);
1465
f104d082 1466 if(type->type == ARRAY){
1467 crc = getTypeChecksum(crc,((field_t*)type->fields.array[0])->type);
1468 } else if(type->type ==SEQUENCE) {
1469 crc = getTypeChecksum(crc,((field_t*)type->fields.array[0])->type);
1470 crc = getTypeChecksum(crc,((field_t*)type->fields.array[1])->type);
1471 } else if(type->type == STRUCT || type->type == UNION){
90395b4b 1472 for(pos =0; pos < type->fields.position; pos++){
90699b2b 1473 fld = (field_t *) type->fields.array[pos];
90395b4b 1474 crc = partial_crc32(fld->name,crc);
1475 crc = getTypeChecksum(crc, fld->type);
1476 }
1477 }else if(type->type == ENUM){
1478 for(pos = 0; pos < type->labels.position; pos++)
1479 crc = partial_crc32((char*)type->labels.array[pos],crc);
1480 }
1481
1482 return crc;
1483}
1484
1485
1486/* Event type descriptors */
90699b2b 1487void freeType(type_descriptor_t * tp)
90395b4b 1488{
1489 int pos2;
90699b2b 1490 field_t *f;
90395b4b 1491
1492 if(tp->fmt != NULL) free(tp->fmt);
1493 if(tp->type == ENUM) {
1494 for(pos2 = 0; pos2 < tp->labels.position; pos2++) {
1495 free(tp->labels.array[pos2]);
1496 }
1497 sequence_dispose(&(tp->labels));
f104d082 1498 for(pos2 = 0; pos2 < tp->labels_values.position; pos2++) {
1499 free(tp->labels_values.array[pos2]);
1500 }
1501 sequence_dispose(&(tp->labels_values));
90395b4b 1502 }
1503 if(tp->type == STRUCT) {
1504 for(pos2 = 0; pos2 < tp->fields.position; pos2++) {
90699b2b 1505 f = (field_t *) tp->fields.array[pos2];
90395b4b 1506 free(f->name);
1507 free(f->description);
1508 free(f);
1509 }
1510 sequence_dispose(&(tp->fields));
1511 }
1512}
1513
90699b2b 1514void freeNamedType(table_t * t)
90395b4b 1515{
1516 int pos;
90699b2b 1517 type_descriptor_t * td;
90395b4b 1518
1519 for(pos = 0 ; pos < t->keys.position; pos++) {
1520 free((char *)t->keys.array[pos]);
90699b2b 1521 td = (type_descriptor_t*)t->values.array[pos];
90395b4b 1522 freeType(td);
1523 free(td);
1524 }
1525}
1526
90699b2b 1527void freeTypes(sequence_t *t)
90395b4b 1528{
a0c1f622 1529 int pos;
90699b2b 1530 type_descriptor_t *tp;
90395b4b 1531
1532 for(pos = 0 ; pos < t->position; pos++) {
90699b2b 1533 tp = (type_descriptor_t *)t->array[pos];
90395b4b 1534 freeType(tp);
1535 free(tp);
1536 }
1537}
1538
90699b2b 1539void freeEvents(sequence_t *t)
90395b4b 1540{
1541 int pos;
90699b2b 1542 event_t *ev;
90395b4b 1543
1544 for(pos = 0 ; pos < t->position; pos++) {
90699b2b 1545 ev = (event_t *) t->array[pos];
90395b4b 1546 free(ev->name);
1547 free(ev->description);
f104d082 1548 sequence_dispose(&ev->fields);
90395b4b 1549 free(ev);
1550 }
1551
1552}
1553
1554
1555/* Extensible array */
1556
90699b2b 1557void sequence_init(sequence_t *t)
90395b4b 1558{
1559 t->size = 10;
1560 t->position = 0;
1561 t->array = (void **)memAlloc(t->size * sizeof(void *));
1562}
1563
90699b2b 1564void sequence_dispose(sequence_t *t)
90395b4b 1565{
1566 t->size = 0;
1567 free(t->array);
1568 t->array = NULL;
1569}
1570
90699b2b 1571void sequence_push(sequence_t *t, void *elem)
90395b4b 1572{
1573 void **tmp;
1574
1575 if(t->position >= t->size) {
1576 tmp = t->array;
1577 t->array = (void **)memAlloc(t->size * 2 * sizeof(void *));
1578 memcpy(t->array, tmp, t->size * sizeof(void *));
1579 t->size = t->size * 2;
1580 free(tmp);
1581 }
1582 t->array[t->position] = elem;
1583 t->position++;
1584}
1585
90699b2b 1586void *sequence_pop(sequence_t *t)
90395b4b 1587{
845a3be5 1588 if(t->position == 0) printf("Error : trying to pop an empty sequence");
1589 return t->array[--t->position];
90395b4b 1590}
1591
1592
1593/* Hash table API, implementation is just linear search for now */
1594
90699b2b 1595void table_init(table_t *t)
90395b4b 1596{
1597 sequence_init(&(t->keys));
1598 sequence_init(&(t->values));
1599}
1600
90699b2b 1601void table_dispose(table_t *t)
90395b4b 1602{
1603 sequence_dispose(&(t->keys));
1604 sequence_dispose(&(t->values));
1605}
1606
90699b2b 1607void table_insert(table_t *t, char *key, void *value)
90395b4b 1608{
1609 sequence_push(&(t->keys),key);
1610 sequence_push(&(t->values),value);
1611}
1612
90699b2b 1613void *table_find(table_t *t, char *key)
90395b4b 1614{
1615 int pos;
1616 for(pos = 0 ; pos < t->keys.position; pos++) {
1617 if(strcmp((char *)key,(char *)t->keys.array[pos]) == 0)
1618 return(t->values.array[pos]);
1619 }
1620 return NULL;
1621}
1622
90699b2b 1623void table_insert_int(table_t *t, int *key, void *value)
90395b4b 1624{
1625 sequence_push(&(t->keys),key);
1626 sequence_push(&(t->values),value);
1627}
1628
90699b2b 1629void *table_find_int(table_t *t, int *key)
90395b4b 1630{
1631 int pos;
1632 for(pos = 0 ; pos < t->keys.position; pos++) {
1633 if(*key == *(int *)t->keys.array[pos])
1634 return(t->values.array[pos]);
1635 }
1636 return NULL;
1637}
1638
1639
1640/* Concatenate strings */
1641
1642char *appendString(char *s, char *suffix)
1643{
1644 char *tmp;
1645 if(suffix == NULL) return s;
1646
1647 tmp = (char *)memAlloc(strlen(s) + strlen(suffix) + 1);
1648 strcpy(tmp,s);
1649 strcat(tmp,suffix);
1650 return tmp;
1651}
This page took 0.101562 seconds and 4 git commands to generate.