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