git-svn-id: http://ltt.polymtl.ca/svn@151 04897980-b3bd-0310-b5e0-8ef037075253
[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>
39#include <linux/errno.h>
40
41
42#include "parser.h"
43
44
45/*****************************************************************************
46 *Function name
47 * getSize : translate from string to integer
48 *Input params
49 * in : input file handle
50 *Return values
51 * size
52 *****************************************************************************/
53
54int getSize(parse_file *in)
55{
56 char *token;
57
58 token = getToken(in);
59 if(in->type == NUMBER) {
60 if(strcmp(token,"1") == 0) return 0;
61 else if(strcmp(token,"2") == 0) return 1;
62 else if(strcmp(token,"4") == 0) return 2;
63 else if(strcmp(token,"8") == 0) return 3;
64 }
65 else if(in->type == NAME) {
66 if(strcmp(token,"short") == 0) return 4;
67 else if(strcmp(token,"medium") == 0) return 5;
68 else if(strcmp(token,"long") == 0) return 6;
69 }
70 in->error(in,"incorrect size specification");
71 return -1;
72}
73
74/*****************************************************************************
75 *Function name
76 * error_callback : print out error info
77 *Input params
78 * in : input file handle
79 * msg : message to be printed
80 ****************************************************************************/
81
82void error_callback(parse_file *in, char *msg)
83{
84 if(in)
85 printf("Error in file %s, line %d: %s\n", in->name, in->lineno, msg);
86 else
87 printf("%s\n",msg);
88 exit(1);
89}
90
91/*****************************************************************************
92 *Function name
93 * memAlloc : allocate memory
94 *Input params
95 * size : required memory size
96 *return value
97 * void * : pointer to allocate memory or NULL
98 ****************************************************************************/
99
100void * memAlloc(int size)
101{
963b5f2d 102 void * addr;
103 if(size == 0) return NULL;
104 addr = malloc(size);
6cd62ccf 105 if(!addr){
106 printf("Failed to allocate memory");
107 exit(1);
108 }
109 return addr;
110}
111
112/*****************************************************************************
113 *Function name
114 * allocAndCopy : allocate memory and initialize it
115 *Input params
116 * str : string to be put in memory
117 *return value
118 * char * : pointer to allocate memory or NULL
119 ****************************************************************************/
120
121char *allocAndCopy(char *str)
122{
963b5f2d 123 char * addr;
124 if(str == NULL) return NULL;
125 addr = (char *)memAlloc(strlen(str)+1);
6cd62ccf 126 strcpy(addr,str);
127 return addr;
128}
129
963b5f2d 130/**************************************************************************
131 * Function :
132 * getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute
133 * getValueStrAttribute
134 * Description :
135 * Read the attribute from the input file.
136 *
137 * Parameters :
138 * in , input file handle.
139 *
140 * Return values :
141 * address of the attribute.
142 *
143 **************************************************************************/
144
145char * getNameAttribute(parse_file *in)
146{
147 char * token, car;
148 token = getName(in);
149 if(strcmp("name",token))in->error(in,"name was expected");
150 getEqual(in);
151
152 car = seekNextChar(in);
153 if(car == EOF)in->error(in,"name was expected");
154 else if(car == '\"')token = getQuotedString(in);
155 else token = getName(in);
156 return token;
157}
158
159char * getFormatAttribute(parse_file *in)
160{
161 char * token;
162
163 //format is an option
164 token = getToken(in);
bf410332 165 if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
963b5f2d 166 ungetToken(in);
167 return NULL;
168 }
169
170 if(strcmp("format",token))in->error(in,"format was expected");
171 getEqual(in);
172 token = getQuotedString(in);
173 return token;
174}
175
176int getSizeAttribute(parse_file *in)
177{
178 char * token;
179 getName(in);
180 getEqual(in);
181
182 return getSize(in);
183}
184
185int getValueAttribute(parse_file *in)
186{
187 char * token;
188 getName(in);
189 getEqual(in);
190
191 return getNumber(in);
192}
193
194//for <label name=label_name value=n/>, value is an option
195char * getValueStrAttribute(parse_file *in)
196{
197 char * token;
198
199 token = getToken(in);
200 if(strcmp("/",token) == 0){
201 ungetToken(in);
202 return NULL;
203 }
204
205 if(strcmp("value",token))in->error(in,"value was expected");
206 getEqual(in);
207 token = getToken(in);
208 if(in->type != NUMBER) in->error(in,"number was expected");
209 return token;
210}
211
212char * getDescription(parse_file *in)
213{
214 long int pos;
215 char * token, car, *str;
216
217 pos = ftell(in->fp);
218
219 getLAnglebracket(in);
220 token = getName(in);
221 if(strcmp("description",token)){
222 fseek(in->fp, pos, SEEK_SET);
223 return NULL;
224 }
225
226 getRAnglebracket(in);
227
228 pos = 0;
229 while((car = getc(in->fp)) != EOF) {
230 if(car == '<') break;
231 if(car == '\0') continue;
232 in->buffer[pos] = car;
233 pos++;
234 }
235 if(car == EOF)in->error(in,"not a valid description");
236 in->buffer[pos] = '\0';
237
238 str = allocAndCopy(in->buffer);
239
240 getForwardslash(in);
241 token = getName(in);
242 if(strcmp("description", token))in->error(in,"not a valid description");
243 getRAnglebracket(in);
244
245 return str;
246}
247
248/*****************************************************************************
249 *Function name
250 * parseFacility : generate event list
251 *Input params
252 * in : input file handle
253 * fac : empty facility
254 *Output params
255 * fac : facility filled with event list
256 ****************************************************************************/
257
258void parseFacility(parse_file *in, facility * fac)
259{
260 char * token;
261 event *ev;
262
263 fac->name = allocAndCopy(getNameAttribute(in));
264 getRAnglebracket(in);
265
ed9d56bd 266 fac->description = getDescription(in);
963b5f2d 267
268 while(1){
269 getLAnglebracket(in);
270
271 token = getToken(in);
272 if(in->type == ENDFILE)
273 in->error(in,"the definition of the facility is not finished");
274
275 if(strcmp("event",token) == 0){
276 ev = (event*) memAlloc(sizeof(event));
277 sequence_push(&(fac->events),ev);
278 parseEvent(in,ev, &(fac->unnamed_types), &(fac->named_types));
279 }else if(strcmp("type",token) == 0){
280 parseTypeDefinition(in, &(fac->unnamed_types), &(fac->named_types));
281 }else if(in->type == FORWARDSLASH){
282 break;
283 }else in->error(in,"event or type token expected\n");
284 }
285
286 token = getName(in);
287 if(strcmp("facility",token)) in->error(in,"not the end of the facility");
288 getRAnglebracket(in); //</facility>
289}
6cd62ccf 290
291/*****************************************************************************
292 *Function name
293 * parseEvent : generate event from event definition
294 *Input params
295 * in : input file handle
296 * ev : new event
963b5f2d 297 * unnamed_types : array of unamed types
298 * named_types : array of named types
6cd62ccf 299 *Output params
300 * ev : new event (parameters are passed to it)
301 ****************************************************************************/
302
303void parseEvent(parse_file *in, event * ev, sequence * unnamed_types,
304 table * named_types)
305{
306 char *token;
307 type_descriptor *t;
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;
353 field *f;
354
963b5f2d 355 f = (field *)memAlloc(sizeof(field));
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;
581 table_insert(named_types,allocAndCopy(name),t);
582 }
583 return t;
584}
585
586/*****************************************************************************
587 *Function name
588 * parseTypeDefinition : get type information from type definition
589 *Input params
590 * in : input file handle
963b5f2d 591 * unnamed_types : array of unamed types
592 * named_types : array of named types
6cd62ccf 593 *****************************************************************************/
594
595void parseTypeDefinition(parse_file * in, sequence * unnamed_types,
596 table * named_types)
597{
598 char *token;
599 type_descriptor *t;
600
963b5f2d 601 token = getNameAttribute(in);
6cd62ccf 602 t = find_named_type(token, named_types);
6cd62ccf 603
604 if(t->type != NONE) in->error(in,"redefinition of named type");
963b5f2d 605 getRAnglebracket(in); //<type name=type_name>
606 getLAnglebracket(in); //<struct>
607 token = getName(in);
608 if(strcmp("struct",token))in->error(in,"not a valid type definition");
609 ungetToken(in);
6cd62ccf 610 parseType(in,t, unnamed_types, named_types);
963b5f2d 611
612 //</type>
613 getLAnglebracket(in);
614 getForwardslash(in);
615 token = getName(in);
616 if(strcmp("type",token))in->error(in,"not a valid type definition");
617 getRAnglebracket(in); //</type>
6cd62ccf 618}
619
620/**************************************************************************
621 * Function :
963b5f2d 622 * getComa, getName, getNumber, getEqual
6cd62ccf 623 * Description :
624 * Read a token from the input file, check its type, return it scontent.
625 *
626 * Parameters :
627 * in , input file handle.
628 *
629 * Return values :
630 * address of token content.
631 *
632 **************************************************************************/
633
634char *getName(parse_file * in)
635{
636 char *token;
637
638 token = getToken(in);
639 if(in->type != NAME) in->error(in,"Name token was expected");
640 return token;
641}
642
643int getNumber(parse_file * in)
644{
645 char *token;
646
647 token = getToken(in);
648 if(in->type != NUMBER) in->error(in, "Number token was expected");
649 return atoi(token);
650}
651
963b5f2d 652char *getForwardslash(parse_file * in)
6cd62ccf 653{
654 char *token;
655
656 token = getToken(in);
963b5f2d 657 if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
6cd62ccf 658 return token;
659}
660
963b5f2d 661char *getLAnglebracket(parse_file * in)
6cd62ccf 662{
663 char *token;
664
665 token = getToken(in);
963b5f2d 666 if(in->type != LANGLEBRACKET) in->error(in, "Left angle bracket was expected");
6cd62ccf 667 return token;
668}
669
963b5f2d 670char *getRAnglebracket(parse_file * in)
6cd62ccf 671{
672 char *token;
673
674 token = getToken(in);
963b5f2d 675 if(in->type != RANGLEBRACKET) in->error(in, "Right angle bracket was expected");
6cd62ccf 676 return token;
677}
678
679char *getQuotedString(parse_file * in)
680{
681 char *token;
682
683 token = getToken(in);
684 if(in->type != QUOTEDSTRING) in->error(in, "quoted string was expected");
685 return token;
686}
687
963b5f2d 688char * getEqual(parse_file *in)
6cd62ccf 689{
690 char *token;
691
692 token = getToken(in);
963b5f2d 693 if(in->type != EQUAL) in->error(in, "equal was expected");
6cd62ccf 694 return token;
695}
696
963b5f2d 697char seekNextChar(parse_file *in)
6cd62ccf 698{
963b5f2d 699 char car;
700 while((car = getc(in->fp)) != EOF) {
701 if(!isspace(car)){
702 ungetc(car,in->fp);
703 return car;
704 }
705 }
706 return EOF;
6cd62ccf 707}
708
709/******************************************************************
710 * Function :
711 * getToken, ungetToken
712 * Description :
713 * Read a token from the input file and return its type and content.
714 * Line numbers are accounted for and whitespace/comments are skipped.
715 *
716 * Parameters :
717 * in, input file handle.
718 *
719 * Return values :
720 * address of token content.
721 *
722 ******************************************************************/
723
724void ungetToken(parse_file * in)
725{
726 in->unget = 1;
727}
728
729char *getToken(parse_file * in)
730{
731 FILE *fp = in->fp;
732 char car, car1;
733 int pos = 0, escaped;
734
735 if(in->unget == 1) {
736 in->unget = 0;
737 return in->buffer;
738 }
739
740 /* skip whitespace and comments */
741
742 while((car = getc(fp)) != EOF) {
743 if(car == '/') {
744 car1 = getc(fp);
745 if(car1 == '*') skipComment(in);
746 else if(car1 == '/') skipEOL(in);
747 else {
748 car1 = ungetc(car1,fp);
749 break;
750 }
751 }
752 else if(car == '\n') in->lineno++;
753 else if(!isspace(car)) break;
754 }
755
756 switch(car) {
757 case EOF:
758 in->type = ENDFILE;
759 break;
963b5f2d 760 case '/':
761 in->type = FORWARDSLASH;
6cd62ccf 762 in->buffer[pos] = car;
763 pos++;
764 break;
963b5f2d 765 case '<':
766 in->type = LANGLEBRACKET;
6cd62ccf 767 in->buffer[pos] = car;
768 pos++;
769 break;
963b5f2d 770 case '>':
771 in->type = RANGLEBRACKET;
6cd62ccf 772 in->buffer[pos] = car;
773 pos++;
774 break;
775 case '=':
776 in->type = EQUAL;
777 in->buffer[pos] = car;
778 pos++;
779 break;
780 case '"':
781 escaped = 0;
782 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
783 if(car == '\\' && escaped == 0) {
784 in->buffer[pos] = car;
785 pos++;
786 escaped = 1;
787 continue;
788 }
789 if(car == '"' && escaped == 0) break;
790 if(car == '\n' && escaped == 0) {
791 in->error(in, "non escaped newline inside quoted string");
792 }
793 if(car == '\n') in->lineno++;
794 in->buffer[pos] = car;
795 pos++;
796 escaped = 0;
797 }
798 if(car == EOF) in->error(in,"no ending quotemark");
799 if(pos == BUFFER_SIZE) in->error(in, "quoted string token too large");
800 in->type = QUOTEDSTRING;
801 break;
802 default:
803 if(isdigit(car)) {
804 in->buffer[pos] = car;
805 pos++;
806 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
807 if(!isdigit(car)) {
808 ungetc(car,fp);
809 break;
810 }
811 in->buffer[pos] = car;
812 pos++;
813 }
814 if(car == EOF) ungetc(car,fp);
815 if(pos == BUFFER_SIZE) in->error(in, "number token too large");
816 in->type = NUMBER;
817 }
818 else if(isalpha(car)) {
819 in->buffer[0] = car;
820 pos = 1;
821 while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
822 if(!isalnum(car)) {
823 ungetc(car,fp);
824 break;
825 }
826 in->buffer[pos] = car;
827 pos++;
828 }
829 if(car == EOF) ungetc(car,fp);
830 if(pos == BUFFER_SIZE) in->error(in, "name token too large");
831 in->type = NAME;
832 }
833 else in->error(in, "invalid character, unrecognized token");
834 }
835 in->buffer[pos] = 0;
836 return in->buffer;
837}
838
839void skipComment(parse_file * in)
840{
841 char car;
842 while((car = getc(in->fp)) != EOF) {
843 if(car == '\n') in->lineno++;
844 else if(car == '*') {
845 car = getc(in->fp);
846 if(car ==EOF) break;
847 if(car == '/') return;
848 ungetc(car,in->fp);
849 }
850 }
851 if(car == EOF) in->error(in,"comment begining with '/*' has no ending '*/'");
852}
853
854void skipEOL(parse_file * in)
855{
856 char car;
857 while((car = getc(in->fp)) != EOF) {
858 if(car == '\n') {
859 ungetc(car,in->fp);
860 break;
861 }
862 }
863 if(car == EOF)ungetc(car, in->fp);
864}
865
866int isalpha(char c)
867{
868 int i,j;
869 if(c == '_')return 1;
870 i = c - 'a';
871 j = c - 'A';
872 if((i>=0 && i<26) || (j>=0 && j<26)) return 1;
873 return 0;
874}
875
876int isalnum(char c)
877{
878 return (isalpha(c) || isdigit(c));
879}
880
881/*****************************************************************************
882 *Function name
883 * checkNamedTypesImplemented : check if all named types have definition
884 ****************************************************************************/
885
886void checkNamedTypesImplemented(table * named_types)
887{
888 type_descriptor *t;
889 int pos;
890 char str[256];
891
892 for(pos = 0 ; pos < named_types->values.position; pos++) {
893 t = (type_descriptor *) named_types->values.array[pos];
894 if(t->type == NONE){
895 sprintf(str,"named type '%s' has no definition",(char*)named_types->keys.array[pos]);
896 error_callback(NULL,str);
897 }
898 }
899}
900
901
902/*****************************************************************************
903 *Function name
904 * generateChecksum : generate checksum for the facility
905 *Input Params
906 * facName : name of facility
907 *Output Params
908 * checksum : checksum for the facility
909 ****************************************************************************/
910
911void generateChecksum( char* facName, unsigned long * checksum, sequence * events)
912{
913 unsigned long crc ;
963b5f2d 914 int pos;
6cd62ccf 915 event * ev;
916 char str[256];
917
918 crc = crc32(facName);
919 for(pos = 0; pos < events->position; pos++){
920 ev = (event *)(events->array[pos]);
6cd62ccf 921 crc = partial_crc32(ev->name,crc);
963b5f2d 922 if(!ev->type) continue; //event without type
6cd62ccf 923 if(ev->type->type != STRUCT){
924 sprintf(str,"event '%s' has a type other than STRUCT",ev->name);
925 error_callback(NULL, str);
926 }
963b5f2d 927 crc = getTypeChecksum(crc, ev->type);
6cd62ccf 928 }
929 *checksum = crc;
930}
931
932/*****************************************************************************
933 *Function name
934 * getTypeChecksum : generate checksum by type info
935 *Input Params
936 * crc : checksum generated so far
937 * type : type descriptor containing type info
938 *Return value
939 * unsigned long : checksum
940 *****************************************************************************/
941
963b5f2d 942unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
6cd62ccf 943{
944 unsigned long crc = aCrc;
945 char * str = NULL, buf[16];
963b5f2d 946 int flag = 0, pos;
6cd62ccf 947 field * fld;
6cd62ccf 948
949 switch(type->type){
950 case INT:
951 str = intOutputTypes[type->size];
952 break;
953 case UINT:
954 str = uintOutputTypes[type->size];
955 break;
956 case FLOAT:
957 str = floatOutputTypes[type->size];
958 break;
959 case STRING:
960 str = allocAndCopy("string");
961 flag = 1;
962 break;
963 case ENUM:
964 str = appendString("enum ", uintOutputTypes[type->size]);
965 flag = 1;
966 break;
967 case ARRAY:
968 sprintf(buf,"%d\0",type->size);
969 str = appendString("array ",buf);
970 flag = 1;
971 break;
972 case SEQUENCE:
973 sprintf(buf,"%d\0",type->size);
974 str = appendString("sequence ",buf);
975 flag = 1;
976 break;
977 case STRUCT:
978 str = allocAndCopy("struct");
979 flag = 1;
980 break;
963b5f2d 981 case UNION:
982 str = allocAndCopy("union");
983 flag = 1;
984 break;
6cd62ccf 985 default:
986 error_callback(NULL, "named type has no definition");
987 break;
988 }
989
990 crc = partial_crc32(str,crc);
991 if(flag) free(str);
992
993 if(type->fmt) crc = partial_crc32(type->fmt,crc);
994
995 if(type->type == ARRAY || type->type == SEQUENCE){
963b5f2d 996 crc = getTypeChecksum(crc,type->nested_type);
997 }else if(type->type == STRUCT || type->type == UNION){
998 for(pos =0; pos < type->fields.position; pos++){
999 fld = (field *) type->fields.array[pos];
1000 crc = partial_crc32(fld->name,crc);
1001 crc = getTypeChecksum(crc, fld->type);
1002 }
6cd62ccf 1003 }else if(type->type == ENUM){
1004 for(pos = 0; pos < type->labels.position; pos++)
963b5f2d 1005 crc = partial_crc32((char*)type->labels.array[pos],crc);
6cd62ccf 1006 }
1007
1008 return crc;
1009}
1010
1011
1012/* Event type descriptors */
1013void freeType(type_descriptor * tp)
1014{
1015 int pos2;
1016 field *f;
1017
1018 if(tp->fmt != NULL) free(tp->fmt);
1019 if(tp->type == ENUM) {
1020 for(pos2 = 0; pos2 < tp->labels.position; pos2++) {
1021 free(tp->labels.array[pos2]);
1022 }
1023 sequence_dispose(&(tp->labels));
1024 }
1025 if(tp->type == STRUCT) {
1026 for(pos2 = 0; pos2 < tp->fields.position; pos2++) {
1027 f = (field *) tp->fields.array[pos2];
1028 free(f->name);
1029 free(f->description);
1030 free(f);
1031 }
1032 sequence_dispose(&(tp->fields));
1033 }
1034}
1035
1036void freeNamedType(table * t)
1037{
1038 int pos;
1039 type_descriptor * td;
1040
1041 for(pos = 0 ; pos < t->keys.position; pos++) {
1042 free((char *)t->keys.array[pos]);
1043 td = (type_descriptor*)t->values.array[pos];
1044 freeType(td);
1045 free(td);
1046 }
1047}
1048
1049void freeTypes(sequence *t)
1050{
1051 int pos, pos2;
1052 type_descriptor *tp;
1053 field *f;
1054
1055 for(pos = 0 ; pos < t->position; pos++) {
1056 tp = (type_descriptor *)t->array[pos];
1057 freeType(tp);
1058 free(tp);
1059 }
1060}
1061
1062void freeEvents(sequence *t)
1063{
1064 int pos;
1065 event *ev;
1066
1067 for(pos = 0 ; pos < t->position; pos++) {
1068 ev = (event *) t->array[pos];
1069 free(ev->name);
1070 free(ev->description);
1071 free(ev);
1072 }
1073
1074}
1075
1076
1077/* Extensible array */
1078
1079void sequence_init(sequence *t)
1080{
1081 t->size = 10;
1082 t->position = 0;
1083 t->array = (void **)memAlloc(t->size * sizeof(void *));
1084}
1085
1086void sequence_dispose(sequence *t)
1087{
1088 t->size = 0;
1089 free(t->array);
1090 t->array = NULL;
1091}
1092
1093void sequence_push(sequence *t, void *elem)
1094{
1095 void **tmp;
1096
1097 if(t->position >= t->size) {
1098 tmp = t->array;
1099 t->array = (void **)memAlloc(t->size * 2 * sizeof(void *));
1100 memcpy(t->array, tmp, t->size * sizeof(void *));
1101 t->size = t->size * 2;
1102 free(tmp);
1103 }
1104 t->array[t->position] = elem;
1105 t->position++;
1106}
1107
1108void *sequence_pop(sequence *t)
1109{
1110 return t->array[t->position--];
1111}
1112
1113
1114/* Hash table API, implementation is just linear search for now */
1115
1116void table_init(table *t)
1117{
1118 sequence_init(&(t->keys));
1119 sequence_init(&(t->values));
1120}
1121
1122void table_dispose(table *t)
1123{
1124 sequence_dispose(&(t->keys));
1125 sequence_dispose(&(t->values));
1126}
1127
1128void table_insert(table *t, char *key, void *value)
1129{
1130 sequence_push(&(t->keys),key);
1131 sequence_push(&(t->values),value);
1132}
1133
1134void *table_find(table *t, char *key)
1135{
1136 int pos;
1137 for(pos = 0 ; pos < t->keys.position; pos++) {
1138 if(strcmp((char *)key,(char *)t->keys.array[pos]) == 0)
1139 return(t->values.array[pos]);
1140 }
1141 return NULL;
1142}
1143
1144void table_insert_int(table *t, int *key, void *value)
1145{
1146 sequence_push(&(t->keys),key);
1147 sequence_push(&(t->values),value);
1148}
1149
1150void *table_find_int(table *t, int *key)
1151{
1152 int pos;
1153 for(pos = 0 ; pos < t->keys.position; pos++) {
1154 if(*key == *(int *)t->keys.array[pos])
1155 return(t->values.array[pos]);
1156 }
1157 return NULL;
1158}
1159
1160
1161/* Concatenate strings */
1162
1163char *appendString(char *s, char *suffix)
1164{
1165 char *tmp;
963b5f2d 1166 if(suffix == NULL) return s;
6cd62ccf 1167
1168 tmp = (char *)memAlloc(strlen(s) + strlen(suffix) + 1);
1169 strcpy(tmp,s);
1170 strcat(tmp,suffix);
1171 return tmp;
1172}
1173
1174
This page took 0.067271 seconds and 4 git commands to generate.