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