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