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