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