14bc6ddd720d2b061ba74ad26e64cf8e8d25e85d
3 genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* This program reads the ".event" event definitions input files
24 specified as command line arguments and generates corresponding
25 ".c" and ".h" files required to trace such events in the kernel.
27 The program uses a very simple tokenizer, called from a hand written
28 recursive descent parser to fill a data structure describing the events.
29 The result is a sequence of events definitions which refer to type
32 A table of named types is maintained to allow refering to types by name
33 when the same type is used at several places. Finally a sequence of
34 all types is maintained to facilitate the freeing of all type
35 information when the processing of an ".event" file is finished. */
42 #include <linux/errno.h>
48 /* Named types may be referenced from anywhere */
52 int main(int argc
, char** argv
)
56 char buffer
[BUFFER_SIZE
];
60 printf("At least one event definition file is needed\n");
65 in
.error
= error_callback
;
67 for(i
= 1 ; i
< argc
; i
++) {
69 in
.name
= allocAndCopy(argv
[i
]);
71 in
.fp
= fopen(in
.name
, "r");
73 in
.error(&in
,"cannot open facility input file");
77 token
= getToken(&in
);
78 if(in
.type
== ENDFILE
) break;
80 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
83 if(strcmp("facility",token
) == 0) {
84 fac
= memAlloc(sizeof(facility
));
86 fac
->description
= NULL
;
87 sequence_init(&(fac
->events
));
88 table_init(&(fac
->named_types
));
89 sequence_init(&(fac
->unnamed_types
));
91 parseFacility(&in
, fac
);
93 //check if any namedType is not defined
94 checkNamedTypesImplemented(&fac
->named_types
);
96 else in
.error(&in
,"facility token was expected");
98 generateFile(argv
[i
]);
101 free(fac
->description
);
102 freeEvents(&fac
->events
);
103 sequence_dispose(&fac
->events
);
104 freeNamedType(&fac
->named_types
);
105 table_dispose(&fac
->named_types
);
106 freeTypes(&fac
->unnamed_types
);
107 sequence_dispose(&fac
->unnamed_types
);
119 /*****************************************************************************
121 * generateFile : generate .c and .h file
123 * name : name of event definition file
124 ****************************************************************************/
125 void generateFile(char *name
){
126 char *loadName
, *hName
, *tmp
, *tmp2
;
129 unsigned long checksum
=0;
131 //remove .xml if it exists
132 tmp
= &name
[strlen(name
)-4];
133 if(strcmp(tmp
, ".xml") == 0){
137 tmp
= strrchr(name
,'/');
144 loadName
= appendString("ltt-facility-loader-", tmp
);
145 tmp2
= appendString(loadName
,".h");
148 hName
= appendString("ltt-facility-", tmp
);
149 tmp2
= appendString(hName
,".h");
152 lFp
= fopen(loadName
,"w");
154 printf("Cannot open the file : %s\n",loadName
);
158 hFp
= fopen(hName
,"w");
160 printf("Cannot open the file : %s\n",hName
);
167 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
169 /* generate .h file, event enumeration then structures and functions */
170 fprintf(hFp
, "#ifndef _LTT_FACILITY_%s_H_\n",fac
->capname
);
171 fprintf(hFp
, "#define _LTT_FACILITY_%s_H_\n\n",fac
->capname
);
172 generateEnumEvent(hFp
, fac
->name
, &nbEvent
, checksum
);
173 generateTypeDefs(hFp
);
174 generateStructFunc(hFp
, fac
->name
,checksum
);
175 fprintf(hFp
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
177 /* generate .h file, calls to register the facility at init time */
178 fprintf(lFp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",fac
->capname
);
179 fprintf(lFp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",fac
->capname
);
180 generateLoaderfile(lFp
,fac
->name
,nbEvent
,checksum
);
181 fprintf(lFp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",fac
->capname
);
188 /*****************************************************************************
190 * generateEnumEvent : output event enum to .h file
192 * fp : file to be written to
193 * facName : name of facility
195 * nbEvent : number of events in the facility
196 ****************************************************************************/
197 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
, unsigned long checksum
) {
200 fprintf(fp
,"#include <linux/ltt-log.h>\n\n");
202 fprintf(fp
,"/**** facility handle ****/\n\n");
203 fprintf(fp
,"extern trace_facility_t ltt_facility_%s_%X;\n\n\n",facName
, checksum
);
205 fprintf(fp
,"/**** event type ****/\n\n");
206 fprintf(fp
,"enum %s_event {\n",facName
);
208 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
209 fprintf(fp
,"\t%s", ((event
*)(fac
->events
.array
[pos
]))->name
);
210 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
212 fprintf(fp
,"\n};\n\n\n");
214 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
215 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
216 *nbEvent
= fac
->events
.position
;
220 /*****************************************************************************
222 * printStruct : Generic struct printing function
224 * fp : file to be written to
225 * len : number of fields
226 * array : array of field info
227 * name : basic struct name
228 * facName : name of facility
229 * whichTypeFirst : struct or array/sequence first
230 * hasStrSeq : string or sequence present?
231 * structCount : struct postfix
232 ****************************************************************************/
235 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
236 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
)
241 type_descriptor
* td
;
243 for (pos
= 0; pos
< len
; pos
++) {
244 fld
= (field
*)array
[pos
];
246 if( td
->type
!= STRING
&& td
->type
!= SEQUENCE
&&
248 if (*whichTypeFirst
== 0) {
249 *whichTypeFirst
= 1; //struct first
254 fprintf(fp
,"struct %s_%s",name
, facName
);
256 fprintf(fp
, "_%d {\n",++*structCount
);
261 fprintf(fp
, "\t%s %s; /* %s */\n",
262 getTypeStr(td
),fld
->name
,fld
->description
);
264 if (*whichTypeFirst
== 0) {
265 //string or sequence or array first
270 fprintf(fp
,"} __attribute__ ((packed));\n\n");
277 fprintf(fp
,"} __attribute__ ((packed));\n\n");
282 /*****************************************************************************
284 * generateHfile : Create the typedefs
286 * fp : file to be written to
287 ****************************************************************************/
289 generateTypeDefs(FILE * fp
)
293 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
295 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
296 type_descriptor
* type
=
297 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
298 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
299 "", type
->type_name
, &tmp
, &tmp
, NULL
);
300 fprintf(fp
, "typedef struct _%s %s;\n\n",
301 type
->type_name
, type
->type_name
);
306 /*****************************************************************************
308 * generateEnumDefinition: generate enum definition if it exists
310 * fp : file to be written to
312 ****************************************************************************/
313 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
316 fprintf(fp
,"enum {\n");
317 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
318 fprintf(fp
,"\t%s", type
->labels
.array
[pos
]);
319 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",\n");
321 fprintf(fp
,"\n};\n\n\n");
324 /*****************************************************************************
326 * generateStrucTFunc: output structure and function to .h file
328 * fp : file to be written to
329 * facName : name of facility
330 ****************************************************************************/
331 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
334 type_descriptor
* td
;
336 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
338 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
339 ev
= (event
*) fac
->events
.array
[pos
];
340 //yxx if(ev->nested)continue;
341 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",ev
->name
);
342 if(ev
->type
== 0){ // event without type
343 fprintf(fp
,"static inline void trace_%s_%s(void){\n",facName
,ev
->name
);
344 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, 0, NULL);\n",facName
,checksum
,ev
->name
);
345 fprintf(fp
,"};\n\n\n");
349 //if fields contain enum, print out enum definition
350 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
351 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
352 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
355 //default: no string, array or sequence in the event
360 //structure for kernel
361 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
362 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
);
364 //trace function : function name and parameters
367 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
368 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
369 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
371 if(td
->type
== ARRAY
){
372 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
373 }else if(td
->type
== STRING
){
374 fprintf(fp
,"short int strLength_%d, %s * %s",++strCount
, getTypeStr(td
), fld
->name
);
375 }else if(td
->type
== SEQUENCE
){
376 fprintf(fp
,"%s seqLength_%d, %s * %s",uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
377 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
378 if(pos1
!= ev
->type
->fields
.position
-1)fprintf(fp
,", ");
382 //length of buffer : length of all structures
383 fprintf(fp
,"\tint bufLength = ");
384 for(pos1
=0;pos1
<structCount
;pos1
++){
385 fprintf(fp
,"sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
386 if(pos1
!= structCount
-1) fprintf(fp
," + ");
389 //length of buffer : length of all arrays, sequences and strings
393 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
394 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
396 if(td
->type
== SEQUENCE
|| td
->type
==STRING
||td
->type
==ARRAY
){
397 if(structCount
|| flag
> 0) fprintf(fp
," + ");
398 if(td
->type
== SEQUENCE
) fprintf(fp
,"sizeof(%s) + sizeof(%s) * seqLength_%d",uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
399 else if(td
->type
==STRING
) fprintf(fp
,"strLength_%d + 1", ++strCount
);
400 else if(td
->type
==ARRAY
) fprintf(fp
,"sizeof(%s) * %d", getTypeStr(td
),td
->size
);
401 if(structCount
== 0) flag
= 1;
407 fprintf(fp
,"\tchar buff[bufLength];\n");
409 //declare a char pointer if needed
410 if(structCount
+ hasStrSeq
> 1) fprintf(fp
,"\tchar * ptr = buff;\n");
412 //allocate memory for new struct and initialize it
413 if(whichTypeFirst
== 1){ //struct first
414 for(pos1
=0;pos1
<structCount
;pos1
++){
415 if(pos1
==0) fprintf(fp
,"\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",ev
->name
, facName
,ev
->name
, facName
);
416 else fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
418 }else if(whichTypeFirst
== 2){
419 for(pos1
=0;pos1
<structCount
;pos1
++)
420 fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
424 if(structCount
) fprintf(fp
,"\t//initialize structs\n");
427 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
428 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
430 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
434 if(structCount
> 1) fprintf(fp
,"\n");
436 if(structCount
== 1 && whichTypeFirst
== 1) fprintf(fp
, "\t__1->%s = %s;\n",fld
->name
,fld
->name
);
437 else fprintf(fp
, "\t__%d.%s = %s;\n",structCount
,fld
->name
,fld
->name
);
440 if(structCount
) fprintf(fp
,"\n");
442 //set ptr to the end of first struct if needed;
443 if(whichTypeFirst
== 1 && structCount
+ hasStrSeq
> 1){
444 fprintf(fp
,"\n\t//set ptr to the end of the first struct\n");
445 fprintf(fp
,"\tptr += sizeof(struct %s_%s_1);\n\n",ev
->name
, facName
);
448 //copy struct, sequence and string to buffer
453 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
454 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
456 if(td
->type
!= STRING
&& td
->type
!= SEQUENCE
&& td
->type
!= ARRAY
){
457 if(flag
== 0) structCount
++;
459 if((structCount
> 1 || whichTypeFirst
== 2) && flag
== 1){
460 fprintf(fp
,"\t//copy struct to buffer\n");
461 fprintf(fp
,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",structCount
, ev
->name
, facName
,structCount
);
462 fprintf(fp
,"\tptr += sizeof(struct %s_%s_%d);\n\n",ev
->name
, facName
,structCount
);
464 }else if(td
->type
== SEQUENCE
){
466 fprintf(fp
,"\t//copy sequence length and sequence to buffer\n");
467 fprintf(fp
,"\t*ptr = seqLength_%d;\n",++seqCount
);
468 fprintf(fp
,"\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
469 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * seqLength_%d);\n",fld
->name
, getTypeStr(td
), seqCount
);
470 fprintf(fp
,"\tptr += sizeof(%s) * seqLength_%d;\n\n",getTypeStr(td
), seqCount
);
471 }else if(td
->type
==STRING
){
473 fprintf(fp
,"\t//copy string to buffer\n");
474 fprintf(fp
,"\tif(strLength_%d > 0){\n",++strCount
);
475 fprintf(fp
,"\t\tmemcpy(ptr, %s, strLength_%d + 1);\n", fld
->name
, strCount
);
476 fprintf(fp
,"\t\tptr += strLength_%d + 1;\n",strCount
);
477 fprintf(fp
,"\t}else{\n");
478 fprintf(fp
,"\t\t*ptr = '\\0';\n");
479 fprintf(fp
,"\t\tptr += 1;\n");
480 fprintf(fp
,"\t}\n\n");
481 }else if(td
->type
==ARRAY
){
483 fprintf(fp
,"\t//copy array to buffer\n");
484 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n", fld
->name
, getTypeStr(td
), td
->size
);
485 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n",getTypeStr(td
), td
->size
);
488 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
490 //call trace function
491 fprintf(fp
,"\n\t//call trace function\n");
492 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName
,checksum
,ev
->name
);
493 fprintf(fp
,"};\n\n\n");
498 /*****************************************************************************
500 * getTypeStr : generate type string
502 * td : a type descriptor
504 * char * : type string
505 ****************************************************************************/
506 char * getTypeStr(type_descriptor
* td
){
507 type_descriptor
* t
;
511 return intOutputTypes
[td
->size
];
513 return uintOutputTypes
[td
->size
];
519 return "unsigned long";
527 return floatOutputTypes
[td
->size
];
531 return uintOutputTypes
[td
->size
];
537 return intOutputTypes
[t
->size
];
539 return uintOutputTypes
[t
->size
];
545 return "unsigned long";
553 return floatOutputTypes
[t
->size
];
557 return uintOutputTypes
[t
->size
];
559 error_callback(NULL
,"Nested struct is not supportted");
563 case STRUCT
: //for now we do not support nested struct
564 error_callback(NULL
,"Nested struct is not supportted");
567 error_callback(NULL
,"No type information");
573 /*****************************************************************************
575 * generateLoaderfile: generate a facility loaded .h file
577 * fp : file to be written to
578 * facName : name of facility
579 * nbEvent : number of events in the facility
580 * checksum : checksum for the facility
581 ****************************************************************************/
582 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
){
583 //will be removed later
584 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
586 fprintf(fp
,"EXPORT_SYMBOL(ltt_facility_%s_%X);\n\n",facName
, checksum
);
587 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\tltt_facility_%s_%X\n",
589 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t0x%X\n", checksum
);
590 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\"%s\"\n", facName
);
591 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t%d\n\n", nbEvent
);
This page took 0.057403 seconds and 4 git commands to generate.