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