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