genevent type enhancements and xml split
[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 t->size = getSizeAttribute(in);
517 t->fmt = allocAndCopy(getFormatAttribute(in));
518 getRAnglebracket(in);
519
520 //<label name=label1 value=n/>
521 getLAnglebracket(in);
522 token = getToken(in); //"label" or "/"
523 while(strcmp("label",token) == 0){
524 str = allocAndCopy(getNameAttribute(in));
525 token = getValueStrAttribute(in);
526 if(token){
527 str1 = appendString(str,"=");
528 free(str);
529 str = appendString(str1,token);
530 free(str1);
531 sequence_push(&(t->labels),str);
532 }else
533 sequence_push(&(t->labels),str);
534
535 getForwardslash(in);
536 getRAnglebracket(in);
537
538 //next label definition
539 getLAnglebracket(in);
540 token = getToken(in); //"label" or "/"
541 }
542 if(strcmp("/",token))in->error(in, "not a valid enum definition");
543 token = getName(in);
544 if(strcmp("enum",token))in->error(in, "not a valid enum definition");
545 getRAnglebracket(in); //</label>
546 }
547 else if(strcmp(token,"int") == 0) {
548 t->type = INT;
549 t->size = getSizeAttribute(in);
550 t->fmt = allocAndCopy(getFormatAttribute(in));
551 getForwardslash(in);
552 getRAnglebracket(in);
553 }
554 else if(strcmp(token,"uint") == 0) {
555 t->type = UINT;
556 t->size = getSizeAttribute(in);
557 t->fmt = allocAndCopy(getFormatAttribute(in));
558 getForwardslash(in);
559 getRAnglebracket(in);
560 }
561 else if(strcmp(token,"pointer") == 0) {
562 t->type = POINTER;
563 t->size = 0;
564 t->fmt = allocAndCopy(getFormatAttribute(in));
565 getForwardslash(in);
566 getRAnglebracket(in);
567 }
568 else if(strcmp(token,"long") == 0) {
569 t->type = LONG;
570 t->size = 0;
571 t->fmt = allocAndCopy(getFormatAttribute(in));
572 getForwardslash(in);
573 getRAnglebracket(in);
574 }
575 else if(strcmp(token,"ulong") == 0) {
576 t->type = ULONG;
577 t->size = 0;
578 t->fmt = allocAndCopy(getFormatAttribute(in));
579 getForwardslash(in);
580 getRAnglebracket(in);
581 }
582 else if(strcmp(token,"size_t") == 0) {
583 t->type = SIZE_T;
584 t->size = 0;
585 t->fmt = allocAndCopy(getFormatAttribute(in));
586 getForwardslash(in);
587 getRAnglebracket(in);
588 }
589 else if(strcmp(token,"ssize_t") == 0) {
590 t->type = SSIZE_T;
591 t->size = 0;
592 t->fmt = allocAndCopy(getFormatAttribute(in));
593 getForwardslash(in);
594 getRAnglebracket(in);
595 }
596 else if(strcmp(token,"off_t") == 0) {
597 t->type = OFF_T;
598 t->size = 0;
599 t->fmt = allocAndCopy(getFormatAttribute(in));
600 getForwardslash(in);
601 getRAnglebracket(in);
602 }
603 else if(strcmp(token,"float") == 0) {
604 t->type = FLOAT;
605 t->size = getSizeAttribute(in);
606 t->fmt = allocAndCopy(getFormatAttribute(in));
607 getForwardslash(in);
608 getRAnglebracket(in);
609 }
610 else if(strcmp(token,"string") == 0) {
611 t->type = STRING;
612 t->fmt = allocAndCopy(getFormatAttribute(in));
613 getForwardslash(in);
614 getRAnglebracket(in);
615 }
616 else if(strcmp(token,"typeref") == 0){
617 // Must be a named type
618 if(inType != NULL)
619 in->error(in,"Named type cannot refer to a named type");
620 else {
621 free(t);
622 sequence_pop(unnamed_types);
623 token = getNameAttribute(in);
624 t = find_named_type(token, named_types);
625 getForwardslash(in); //<typeref name=type_name/>
626 getRAnglebracket(in);
627 return t;
628 }
629 }else in->error(in,"not a valid type");
630
631 return t;
632 }
633
634 /*****************************************************************************
635 *Function name
636 * find_named_type : find a named type from hash table
637 *Input params
638 * name : type name
639 * named_types : array of named types
640 *Return values
641 * type_descriptor * : a type descriptor
642 *****************************************************************************/
643
644 type_descriptor * find_named_type(char *name, table * named_types)
645 {
646 type_descriptor *t;
647
648 t = table_find(named_types,name);
649 if(t == NULL) {
650 t = (type_descriptor *)memAlloc(sizeof(type_descriptor));
651 t->type_name = allocAndCopy(name);
652 t->type = NONE;
653 t->fmt = NULL;
654 table_insert(named_types,t->type_name,t);
655 // table_insert(named_types,allocAndCopy(name),t);
656 }
657 return t;
658 }
659
660 /*****************************************************************************
661 *Function name
662 * parseTypeDefinition : get type information from type definition
663 *Input params
664 * in : input file handle
665 * unnamed_types : array of unamed types
666 * named_types : array of named types
667 *****************************************************************************/
668
669 void parseTypeDefinition(parse_file * in, sequence * unnamed_types,
670 table * named_types)
671 {
672 char *token;
673 type_descriptor *t;
674
675 token = getNameAttribute(in);
676 t = find_named_type(token, named_types);
677
678 if(t->type != NONE) in->error(in,"redefinition of named type");
679 getRAnglebracket(in); //<type name=type_name>
680 getLAnglebracket(in); //<struct>
681 token = getName(in);
682 if(strcmp("struct",token))in->error(in,"not a valid type definition");
683 ungetToken(in);
684 parseType(in,t, unnamed_types, named_types);
685
686 //</type>
687 getLAnglebracket(in);
688 getForwardslash(in);
689 token = getName(in);
690 if(strcmp("type",token))in->error(in,"not a valid type definition");
691 getRAnglebracket(in); //</type>
692 }
693
694 /**************************************************************************
695 * Function :
696 * getComa, getName, getNumber, getEqual
697 * Description :
698 * Read a token from the input file, check its type, return it scontent.
699 *
700 * Parameters :
701 * in , input file handle.
702 *
703 * Return values :
704 * address of token content.
705 *
706 **************************************************************************/
707
708 char *getName(parse_file * in)
709 {
710 char *token;
711
712 token = getToken(in);
713 if(in->type != NAME) in->error(in,"Name token was expected");
714 return token;
715 }
716
717 int getNumber(parse_file * in)
718 {
719 char *token;
720
721 token = getToken(in);
722 if(in->type != NUMBER) in->error(in, "Number token was expected");
723 return atoi(token);
724 }
725
726 char *getForwardslash(parse_file * in)
727 {
728 char *token;
729
730 token = getToken(in);
731 if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
732 return token;
733 }
734
735 char *getLAnglebracket(parse_file * in)
736 {
737 char *token;
738
739 token = getToken(in);
740 if(in->type != LANGLEBRACKET) in->error(in, "Left angle bracket was expected");
741 return token;
742 }
743
744 char *getRAnglebracket(parse_file * in)
745 {
746 char *token;
747
748 token = getToken(in);
749 if(in->type != RANGLEBRACKET) in->error(in, "Right angle bracket was expected");
750 return token;
751 }
752
753 char *getQuotedString(parse_file * in)
754 {
755 char *token;
756
757 token = getToken(in);
758 if(in->type != QUOTEDSTRING) in->error(in, "quoted string was expected");
759 return token;
760 }
761
762 char * getEqual(parse_file *in)
763 {
764 char *token;
765
766 token = getToken(in);
767 if(in->type != EQUAL) in->error(in, "equal was expected");
768 return token;
769 }
770
771 char seekNextChar(parse_file *in)
772 {
773 char car;
774 while((car = getc(in->fp)) != EOF) {
775 if(!isspace(car)){
776 ungetc(car,in->fp);
777 return car;
778 }
779 }
780 return EOF;
781 }
782
783 /******************************************************************
784 * Function :
785 * getToken, ungetToken
786 * Description :
787 * Read a token from the input file and return its type and content.
788 * Line numbers are accounted for and whitespace/comments are skipped.
789 *
790 * Parameters :
791 * in, input file handle.
792 *
793 * Return values :
794 * address of token content.
795 *
796 ******************************************************************/
797
798 void ungetToken(parse_file * in)
799 {
800 in->unget = 1;
801 }
802
803 char *getToken(parse_file * in)
804 {
805 FILE *fp = in->fp;
806 char car, car1;
807 int pos = 0, escaped;
808
809 if(in->unget == 1) {
810 in->unget = 0;
811 return in->buffer;
812 }
813
814 /* skip whitespace and comments */
815
816 while((car = getc(fp)) != EOF) {
817 if(car == '/') {
818 car1 = getc(fp);
819 if(car1 == '*') skipComment(in);
820 else if(car1 == '/') skipEOL(in);
821 else {
822 car1 = ungetc(car1,fp);
823 break;
824 }
825 }
826 else if(car == '\n') in->lineno++;
827 else if(!isspace(car)) break;
828 }
829
830 switch(car) {
831 case EOF:
832 in->type = ENDFILE;
833 break;
834 case '/':
835 in->type = FORWARDSLASH;
836 in->buffer[pos] = car;
837 pos++;
838 break;
839 case '<':
840 in->type = LANGLEBRACKET;
841 in->buffer[pos] = car;
842 pos++;
843 break;
844 case '>':
845 in->type = RANGLEBRACKET;
846 in->buffer[pos] = car;
847 pos++;
848 break;
849 case '=':
850 in->type = EQUAL;
851 in->buffer[pos] = car;
852 pos++;
853 break;
854 case '"':
855 escaped = 0;
856 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
857 if(car == '\\' && escaped == 0) {
858 in->buffer[pos] = car;
859 pos++;
860 escaped = 1;
861 continue;
862 }
863 if(car == '"' && escaped == 0) break;
864 if(car == '\n' && escaped == 0) {
865 in->error(in, "non escaped newline inside quoted string");
866 }
867 if(car == '\n') in->lineno++;
868 in->buffer[pos] = car;
869 pos++;
870 escaped = 0;
871 }
872 if(car == EOF) in->error(in,"no ending quotemark");
873 if(pos == BUFFER_SIZE) in->error(in, "quoted string token too large");
874 in->type = QUOTEDSTRING;
875 break;
876 default:
877 if(isdigit(car)) {
878 in->buffer[pos] = car;
879 pos++;
880 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
881 if(!isdigit(car)) {
882 ungetc(car,fp);
883 break;
884 }
885 in->buffer[pos] = car;
886 pos++;
887 }
888 if(car == EOF) ungetc(car,fp);
889 if(pos == BUFFER_SIZE) in->error(in, "number token too large");
890 in->type = NUMBER;
891 }
892 else if(isalpha(car)) {
893 in->buffer[0] = car;
894 pos = 1;
895 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
896 if(!(isalnum(car) || car == '_')) {
897 ungetc(car,fp);
898 break;
899 }
900 in->buffer[pos] = car;
901 pos++;
902 }
903 if(car == EOF) ungetc(car,fp);
904 if(pos == BUFFER_SIZE) in->error(in, "name token too large");
905 in->type = NAME;
906 }
907 else in->error(in, "invalid character, unrecognized token");
908 }
909 in->buffer[pos] = 0;
910 return in->buffer;
911 }
912
913 void skipComment(parse_file * in)
914 {
915 char car;
916 while((car = getc(in->fp)) != EOF) {
917 if(car == '\n') in->lineno++;
918 else if(car == '*') {
919 car = getc(in->fp);
920 if(car ==EOF) break;
921 if(car == '/') return;
922 ungetc(car,in->fp);
923 }
924 }
925 if(car == EOF) in->error(in,"comment begining with '/*' has no ending '*/'");
926 }
927
928 void skipEOL(parse_file * in)
929 {
930 char car;
931 while((car = getc(in->fp)) != EOF) {
932 if(car == '\n') {
933 ungetc(car,in->fp);
934 break;
935 }
936 }
937 if(car == EOF)ungetc(car, in->fp);
938 }
939
940 /*****************************************************************************
941 *Function name
942 * checkNamedTypesImplemented : check if all named types have definition
943 ****************************************************************************/
944
945 void checkNamedTypesImplemented(table * named_types)
946 {
947 type_descriptor *t;
948 int pos;
949 char str[256];
950
951 for(pos = 0 ; pos < named_types->values.position; pos++) {
952 t = (type_descriptor *) named_types->values.array[pos];
953 if(t->type == NONE){
954 sprintf(str,"named type '%s' has no definition",(char*)named_types->keys.array[pos]);
955 error_callback(NULL,str);
956 }
957 }
958 }
959
960
961 /*****************************************************************************
962 *Function name
963 * generateChecksum : generate checksum for the facility
964 *Input Params
965 * facName : name of facility
966 *Output Params
967 * checksum : checksum for the facility
968 ****************************************************************************/
969
970 void generateChecksum( char* facName, unsigned long * checksum, sequence * events)
971 {
972 unsigned long crc ;
973 int pos;
974 event * ev;
975 char str[256];
976
977 crc = crc32(facName);
978 for(pos = 0; pos < events->position; pos++){
979 ev = (event *)(events->array[pos]);
980 crc = partial_crc32(ev->name,crc);
981 if(!ev->type) continue; //event without type
982 if(ev->type->type != STRUCT){
983 sprintf(str,"event '%s' has a type other than STRUCT",ev->name);
984 error_callback(NULL, str);
985 }
986 crc = getTypeChecksum(crc, ev->type);
987 }
988 *checksum = crc;
989 }
990
991 /*****************************************************************************
992 *Function name
993 * getTypeChecksum : generate checksum by type info
994 *Input Params
995 * crc : checksum generated so far
996 * type : type descriptor containing type info
997 *Return value
998 * unsigned long : checksum
999 *****************************************************************************/
1000
1001 unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
1002 {
1003 unsigned long crc = aCrc;
1004 char * str = NULL, buf[16];
1005 int flag = 0, pos;
1006 field * fld;
1007
1008 switch(type->type){
1009 case INT:
1010 str = intOutputTypes[type->size];
1011 break;
1012 case UINT:
1013 str = uintOutputTypes[type->size];
1014 break;
1015 case POINTER:
1016 str = allocAndCopy("void *");
1017 flag = 1;
1018 break;
1019 case LONG:
1020 str = allocAndCopy("long");
1021 flag = 1;
1022 break;
1023 case ULONG:
1024 str = allocAndCopy("unsigned long");
1025 flag = 1;
1026 break;
1027 case SIZE_T:
1028 str = allocAndCopy("size_t");
1029 flag = 1;
1030 break;
1031 case SSIZE_T:
1032 str = allocAndCopy("ssize_t");
1033 flag = 1;
1034 break;
1035 case OFF_T:
1036 str = allocAndCopy("off_t");
1037 flag = 1;
1038 break;
1039 case FLOAT:
1040 str = floatOutputTypes[type->size];
1041 break;
1042 case STRING:
1043 str = allocAndCopy("string");
1044 flag = 1;
1045 break;
1046 case ENUM:
1047 str = appendString("enum ", uintOutputTypes[type->size]);
1048 flag = 1;
1049 break;
1050 case ARRAY:
1051 sprintf(buf,"%d\0",type->size);
1052 str = appendString("array ",buf);
1053 flag = 1;
1054 break;
1055 case SEQUENCE:
1056 sprintf(buf,"%d\0",type->size);
1057 str = appendString("sequence ",buf);
1058 flag = 1;
1059 break;
1060 case STRUCT:
1061 str = allocAndCopy("struct");
1062 flag = 1;
1063 break;
1064 case UNION:
1065 str = allocAndCopy("union");
1066 flag = 1;
1067 break;
1068 default:
1069 error_callback(NULL, "named type has no definition");
1070 break;
1071 }
1072
1073 crc = partial_crc32(str,crc);
1074 if(flag) free(str);
1075
1076 if(type->fmt) crc = partial_crc32(type->fmt,crc);
1077
1078 if(type->type == ARRAY || type->type == SEQUENCE){
1079 crc = getTypeChecksum(crc,type->nested_type);
1080 }else if(type->type == STRUCT || type->type == UNION){
1081 for(pos =0; pos < type->fields.position; pos++){
1082 fld = (field *) type->fields.array[pos];
1083 crc = partial_crc32(fld->name,crc);
1084 crc = getTypeChecksum(crc, fld->type);
1085 }
1086 }else if(type->type == ENUM){
1087 for(pos = 0; pos < type->labels.position; pos++)
1088 crc = partial_crc32((char*)type->labels.array[pos],crc);
1089 }
1090
1091 return crc;
1092 }
1093
1094
1095 /* Event type descriptors */
1096 void freeType(type_descriptor * tp)
1097 {
1098 int pos2;
1099 field *f;
1100
1101 if(tp->fmt != NULL) free(tp->fmt);
1102 if(tp->type == ENUM) {
1103 for(pos2 = 0; pos2 < tp->labels.position; pos2++) {
1104 free(tp->labels.array[pos2]);
1105 }
1106 sequence_dispose(&(tp->labels));
1107 }
1108 if(tp->type == STRUCT) {
1109 for(pos2 = 0; pos2 < tp->fields.position; pos2++) {
1110 f = (field *) tp->fields.array[pos2];
1111 free(f->name);
1112 free(f->description);
1113 free(f);
1114 }
1115 sequence_dispose(&(tp->fields));
1116 }
1117 }
1118
1119 void freeNamedType(table * t)
1120 {
1121 int pos;
1122 type_descriptor * td;
1123
1124 for(pos = 0 ; pos < t->keys.position; pos++) {
1125 free((char *)t->keys.array[pos]);
1126 td = (type_descriptor*)t->values.array[pos];
1127 freeType(td);
1128 free(td);
1129 }
1130 }
1131
1132 void freeTypes(sequence *t)
1133 {
1134 int pos, pos2;
1135 type_descriptor *tp;
1136 field *f;
1137
1138 for(pos = 0 ; pos < t->position; pos++) {
1139 tp = (type_descriptor *)t->array[pos];
1140 freeType(tp);
1141 free(tp);
1142 }
1143 }
1144
1145 void freeEvents(sequence *t)
1146 {
1147 int pos;
1148 event *ev;
1149
1150 for(pos = 0 ; pos < t->position; pos++) {
1151 ev = (event *) t->array[pos];
1152 free(ev->name);
1153 free(ev->description);
1154 free(ev);
1155 }
1156
1157 }
1158
1159
1160 /* Extensible array */
1161
1162 void sequence_init(sequence *t)
1163 {
1164 t->size = 10;
1165 t->position = 0;
1166 t->array = (void **)memAlloc(t->size * sizeof(void *));
1167 }
1168
1169 void sequence_dispose(sequence *t)
1170 {
1171 t->size = 0;
1172 free(t->array);
1173 t->array = NULL;
1174 }
1175
1176 void sequence_push(sequence *t, void *elem)
1177 {
1178 void **tmp;
1179
1180 if(t->position >= t->size) {
1181 tmp = t->array;
1182 t->array = (void **)memAlloc(t->size * 2 * sizeof(void *));
1183 memcpy(t->array, tmp, t->size * sizeof(void *));
1184 t->size = t->size * 2;
1185 free(tmp);
1186 }
1187 t->array[t->position] = elem;
1188 t->position++;
1189 }
1190
1191 void *sequence_pop(sequence *t)
1192 {
1193 return t->array[t->position--];
1194 }
1195
1196
1197 /* Hash table API, implementation is just linear search for now */
1198
1199 void table_init(table *t)
1200 {
1201 sequence_init(&(t->keys));
1202 sequence_init(&(t->values));
1203 }
1204
1205 void table_dispose(table *t)
1206 {
1207 sequence_dispose(&(t->keys));
1208 sequence_dispose(&(t->values));
1209 }
1210
1211 void table_insert(table *t, char *key, void *value)
1212 {
1213 sequence_push(&(t->keys),key);
1214 sequence_push(&(t->values),value);
1215 }
1216
1217 void *table_find(table *t, char *key)
1218 {
1219 int pos;
1220 for(pos = 0 ; pos < t->keys.position; pos++) {
1221 if(strcmp((char *)key,(char *)t->keys.array[pos]) == 0)
1222 return(t->values.array[pos]);
1223 }
1224 return NULL;
1225 }
1226
1227 void table_insert_int(table *t, int *key, void *value)
1228 {
1229 sequence_push(&(t->keys),key);
1230 sequence_push(&(t->values),value);
1231 }
1232
1233 void *table_find_int(table *t, int *key)
1234 {
1235 int pos;
1236 for(pos = 0 ; pos < t->keys.position; pos++) {
1237 if(*key == *(int *)t->keys.array[pos])
1238 return(t->values.array[pos]);
1239 }
1240 return NULL;
1241 }
1242
1243
1244 /* Concatenate strings */
1245
1246 char *appendString(char *s, char *suffix)
1247 {
1248 char *tmp;
1249 if(suffix == NULL) return s;
1250
1251 tmp = (char *)memAlloc(strlen(s) + strlen(suffix) + 1);
1252 strcpy(tmp,s);
1253 strcat(tmp,suffix);
1254 return tmp;
1255 }
1256
1257
This page took 0.065314 seconds and 5 git commands to generate.