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