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>
49 /* Named types may be referenced from anywhere */
53 int main(int argc
, char** argv
)
57 char buffer
[BUFFER_SIZE
];
61 printf("At least one event definition file is needed\n");
66 in
.error
= error_callback
;
68 for(i
= 1 ; i
< argc
; i
++) {
70 in
.name
= allocAndCopy(argv
[i
]);
72 in
.fp
= fopen(in
.name
, "r");
74 in
.error(&in
,"cannot open facility input file");
78 token
= getToken(&in
);
79 if(in
.type
== ENDFILE
) break;
81 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
84 if(strcmp("facility",token
) == 0) {
85 fac
= memAlloc(sizeof(facility
));
87 fac
->description
= NULL
;
88 sequence_init(&(fac
->events
));
89 table_init(&(fac
->named_types
));
90 sequence_init(&(fac
->unnamed_types
));
92 parseFacility(&in
, fac
);
94 //check if any namedType is not defined
95 checkNamedTypesImplemented(&fac
->named_types
);
97 else in
.error(&in
,"facility token was expected");
99 generateFile(argv
[i
]);
102 free(fac
->description
);
103 freeEvents(&fac
->events
);
104 sequence_dispose(&fac
->events
);
105 freeNamedType(&fac
->named_types
);
106 table_dispose(&fac
->named_types
);
107 freeTypes(&fac
->unnamed_types
);
108 sequence_dispose(&fac
->unnamed_types
);
120 /*****************************************************************************
122 * generateFile : generate .c and .h file
124 * name : name of event definition file
125 ****************************************************************************/
126 void generateFile(char *name
){
127 char *cName
, *hName
, *tmp
;
130 unsigned long checksum
=0;
132 //remove .xml if it exists
133 tmp
= &name
[strlen(name
)-4];
134 if(strcmp(tmp
, ".xml") == 0){
138 tmp
= strrchr(name
,'/');
145 cName
= appendString(tmp
,".c");
146 hName
= appendString(tmp
,".h");
147 cFp
= fopen(cName
,"w");
149 printf("Cannot open the file : %s\n",cName
);
153 hFp
= fopen(hName
,"w");
155 printf("Cannot open the file : %s\n",hName
);
162 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
164 /* generate .h file, event enumeration then structures and functions */
165 fprintf(hFp
, "#ifndef _LTT_FACILITY_%s_H_\n",fac
->capname
);
166 fprintf(hFp
, "#define _LTT_FACILITY_%s_H_\n\n",fac
->capname
);
167 generateEnumEvent(hFp
, fac
->name
, &nbEvent
, checksum
);
168 generateTypeDefs(hFp
);
169 generateStructFunc(hFp
, fac
->name
,checksum
);
170 fprintf(hFp
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
172 /* generate .c file, calls to register the facility at init time */
173 generateCfile(cFp
,fac
->name
,nbEvent
,checksum
);
180 /*****************************************************************************
182 * generateEnumEvent : output event enum to .h file
184 * fp : file to be written to
185 * facName : name of facility
187 * nbEvent : number of events in the facility
188 ****************************************************************************/
189 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
, unsigned long checksum
) {
192 fprintf(fp
,"#include <linux/ltt-log.h>\n\n");
194 fprintf(fp
,"/**** facility handle ****/\n\n");
195 fprintf(fp
,"extern trace_facility_t ltt_facility_%s_%X;\n\n\n",facName
, checksum
);
197 fprintf(fp
,"/**** event type ****/\n\n");
198 fprintf(fp
,"enum %s_event {\n",facName
);
200 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
201 fprintf(fp
,"\t%s", ((event
*)(fac
->events
.array
[pos
]))->name
);
202 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
204 fprintf(fp
,"\n};\n\n\n");
206 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
207 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
208 *nbEvent
= fac
->events
.position
;
212 /*****************************************************************************
214 * printStruct : Generic struct printing function
216 * fp : file to be written to
217 * len : number of fields
218 * array : array of field info
219 * name : basic struct name
220 * facName : name of facility
221 * whichTypeFirst : struct or array/sequence first
222 * hasStrSeq : string or sequence present?
223 * structCount : struct postfix
224 ****************************************************************************/
227 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
228 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
)
233 type_descriptor
* td
;
235 for (pos
= 0; pos
< len
; pos
++) {
236 fld
= (field
*)array
[pos
];
238 if( td
->type
!= STRING
&& td
->type
!= SEQUENCE
&&
240 if (*whichTypeFirst
== 0) {
241 *whichTypeFirst
= 1; //struct first
246 fprintf(fp
,"struct %s_%s",name
, facName
);
248 fprintf(fp
, "_%d {\n",++*structCount
);
253 fprintf(fp
, "\t%s %s; /* %s */\n",
254 getTypeStr(td
),fld
->name
,fld
->description
);
256 if (*whichTypeFirst
== 0) {
257 //string or sequence or array first
262 fprintf(fp
,"} __attribute__ ((packed));\n\n");
269 fprintf(fp
,"} __attribute__ ((packed));\n\n");
274 /*****************************************************************************
276 * generateHfile : Create the typedefs
278 * fp : file to be written to
279 ****************************************************************************/
281 generateTypeDefs(FILE * fp
)
285 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
287 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
288 type_descriptor
* type
=
289 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
290 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
291 "", type
->type_name
, &tmp
, &tmp
, NULL
);
292 fprintf(fp
, "typedef struct _%s %s;\n\n",
293 type
->type_name
, type
->type_name
);
298 /*****************************************************************************
300 * generateEnumDefinition: generate enum definition if it exists
302 * fp : file to be written to
304 ****************************************************************************/
305 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
308 fprintf(fp
,"enum {\n");
309 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
310 fprintf(fp
,"\t%s", type
->labels
.array
[pos
]);
311 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",\n");
313 fprintf(fp
,"\n};\n\n\n");
316 /*****************************************************************************
318 * generateStrucTFunc: output structure and function to .h file
320 * fp : file to be written to
321 * facName : name of facility
322 ****************************************************************************/
323 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
326 type_descriptor
* td
;
328 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
330 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
331 ev
= (event
*) fac
->events
.array
[pos
];
332 //yxx if(ev->nested)continue;
333 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",ev
->name
);
334 if(ev
->type
== 0){ // event without type
335 fprintf(fp
,"static inline void trace_%s_%s(void){\n",facName
,ev
->name
);
336 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, 0, NULL);\n",facName
,checksum
,ev
->name
);
337 fprintf(fp
,"};\n\n\n");
341 //if fields contain enum, print out enum definition
342 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
343 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
344 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
347 //default: no string, array or sequence in the event
352 //structure for kernel
353 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
354 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
);
356 //trace function : function name and parameters
359 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
360 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
361 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
363 if(td
->type
== ARRAY
){
364 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
365 }else if(td
->type
== STRING
){
366 fprintf(fp
,"short int strLength_%d, %s * %s",++strCount
, getTypeStr(td
), fld
->name
);
367 }else if(td
->type
== SEQUENCE
){
368 fprintf(fp
,"%s seqLength_%d, %s * %s",uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
369 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
370 if(pos1
!= ev
->type
->fields
.position
-1)fprintf(fp
,", ");
374 //length of buffer : length of all structures
375 fprintf(fp
,"\tint bufLength = ");
376 for(pos1
=0;pos1
<structCount
;pos1
++){
377 fprintf(fp
,"sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
378 if(pos1
!= structCount
-1) fprintf(fp
," + ");
381 //length of buffer : length of all arrays, sequences and strings
385 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
386 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
388 if(td
->type
== SEQUENCE
|| td
->type
==STRING
||td
->type
==ARRAY
){
389 if(structCount
|| flag
> 0) fprintf(fp
," + ");
390 if(td
->type
== SEQUENCE
) fprintf(fp
,"sizeof(%s) + sizeof(%s) * seqLength_%d",uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
391 else if(td
->type
==STRING
) fprintf(fp
,"strLength_%d + 1", ++strCount
);
392 else if(td
->type
==ARRAY
) fprintf(fp
,"sizeof(%s) * %d", getTypeStr(td
),td
->size
);
393 if(structCount
== 0) flag
= 1;
399 fprintf(fp
,"\tchar buff[bufLength];\n");
401 //declare a char pointer if needed
402 if(structCount
+ hasStrSeq
> 1) fprintf(fp
,"\tchar * ptr = buff;\n");
404 //allocate memory for new struct and initialize it
405 if(whichTypeFirst
== 1){ //struct first
406 for(pos1
=0;pos1
<structCount
;pos1
++){
407 if(pos1
==0) fprintf(fp
,"\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",ev
->name
, facName
,ev
->name
, facName
);
408 else fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
410 }else if(whichTypeFirst
== 2){
411 for(pos1
=0;pos1
<structCount
;pos1
++)
412 fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
416 if(structCount
) fprintf(fp
,"\t//initialize structs\n");
419 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
420 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
422 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
426 if(structCount
> 1) fprintf(fp
,"\n");
428 if(structCount
== 1 && whichTypeFirst
== 1) fprintf(fp
, "\t__1->%s = %s;\n",fld
->name
,fld
->name
);
429 else fprintf(fp
, "\t__%d.%s = %s;\n",structCount
,fld
->name
,fld
->name
);
432 if(structCount
) fprintf(fp
,"\n");
434 //set ptr to the end of first struct if needed;
435 if(whichTypeFirst
== 1 && structCount
+ hasStrSeq
> 1){
436 fprintf(fp
,"\n\t//set ptr to the end of the first struct\n");
437 fprintf(fp
,"\tptr += sizeof(struct %s_%s_1);\n\n",ev
->name
, facName
);
440 //copy struct, sequence and string to buffer
445 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
446 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
448 if(td
->type
!= STRING
&& td
->type
!= SEQUENCE
&& td
->type
!= ARRAY
){
449 if(flag
== 0) structCount
++;
451 if((structCount
> 1 || whichTypeFirst
== 2) && flag
== 1){
452 fprintf(fp
,"\t//copy struct to buffer\n");
453 fprintf(fp
,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",structCount
, ev
->name
, facName
,structCount
);
454 fprintf(fp
,"\tptr += sizeof(struct %s_%s_%d);\n\n",ev
->name
, facName
,structCount
);
456 }else if(td
->type
== SEQUENCE
){
458 fprintf(fp
,"\t//copy sequence length and sequence to buffer\n");
459 fprintf(fp
,"\t*ptr = seqLength_%d;\n",++seqCount
);
460 fprintf(fp
,"\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
461 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * seqLength_%d);\n",fld
->name
, getTypeStr(td
), seqCount
);
462 fprintf(fp
,"\tptr += sizeof(%s) * seqLength_%d;\n\n",getTypeStr(td
), seqCount
);
463 }else if(td
->type
==STRING
){
465 fprintf(fp
,"\t//copy string to buffer\n");
466 fprintf(fp
,"\tif(strLength_%d > 0){\n",++strCount
);
467 fprintf(fp
,"\t\tmemcpy(ptr, %s, strLength_%d + 1);\n", fld
->name
, strCount
);
468 fprintf(fp
,"\t\tptr += strLength_%d + 1;\n",strCount
);
469 fprintf(fp
,"\t}else{\n");
470 fprintf(fp
,"\t\t*ptr = '\\0';\n");
471 fprintf(fp
,"\t\tptr += 1;\n");
472 fprintf(fp
,"\t}\n\n");
473 }else if(td
->type
==ARRAY
){
475 fprintf(fp
,"\t//copy array to buffer\n");
476 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n", fld
->name
, getTypeStr(td
), td
->size
);
477 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n",getTypeStr(td
), td
->size
);
480 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
482 //call trace function
483 fprintf(fp
,"\n\t//call trace function\n");
484 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName
,checksum
,ev
->name
);
485 fprintf(fp
,"};\n\n\n");
490 /*****************************************************************************
492 * getTypeStr : generate type string
494 * td : a type descriptor
496 * char * : type string
497 ****************************************************************************/
498 char * getTypeStr(type_descriptor
* td
){
499 type_descriptor
* t
;
503 return intOutputTypes
[td
->size
];
505 return uintOutputTypes
[td
->size
];
511 return "unsigned long";
519 return floatOutputTypes
[td
->size
];
523 return uintOutputTypes
[td
->size
];
529 return intOutputTypes
[t
->size
];
531 return uintOutputTypes
[t
->size
];
537 return "unsigned long";
545 return floatOutputTypes
[t
->size
];
549 return uintOutputTypes
[t
->size
];
551 error_callback(NULL
,"Nested struct is not supportted");
555 case STRUCT
: //for now we do not support nested struct
556 error_callback(NULL
,"Nested struct is not supportted");
559 error_callback(NULL
,"No type information");
565 /*****************************************************************************
567 * generateCfile : generate a .c file
569 * fp : file to be written to
570 * facName : name of facility
571 * nbEvent : number of events in the facility
572 * checksum : checksum for the facility
573 ****************************************************************************/
574 void generateCfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
){
575 //will be removed later
576 fprintf(fp
,"typedef unsigned int trace_facility_t;\n\n");
578 fprintf(fp
,"static unsigned long checksum = %lu;\n\n",checksum
);
579 fprintf(fp
,"/* facility handle */\n");
580 fprintf(fp
,"trace_facility_t facility_%s;\n\n",facName
);
582 fprintf(fp
,"static void __init facility_%s_init(){\n",facName
);
583 fprintf(fp
,"\tfacility_%s = trace_register_facility_by_checksum(\"%s\", checksum,%d);\n",facName
,facName
,nbEvent
);
586 fprintf(fp
,"static void __exit facility_%s_exit(){\n",facName
);
589 fprintf(fp
,"module_init(facility_%s_init);\n",facName
);
590 fprintf(fp
,"module_exit(facility_%s_exit);\n",facName
);
This page took 0.056768 seconds and 5 git commands to generate.