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 generateLoaderfile(lFp
,fac
->name
,nbEvent
,checksum
,fac
->capname
);
185 /*****************************************************************************
187 * generateEnumEvent : output event enum to .h file
189 * fp : file to be written to
190 * facName : name of facility
192 * nbEvent : number of events in the facility
193 ****************************************************************************/
194 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
, unsigned long checksum
) {
197 fprintf(fp
,"#include <linux/ltt-log.h>\n\n");
199 fprintf(fp
,"/**** facility handle ****/\n\n");
200 fprintf(fp
,"extern trace_facility_t ltt_facility_%s_%X;\n\n\n",facName
, checksum
);
202 fprintf(fp
,"/**** event type ****/\n\n");
203 fprintf(fp
,"enum %s_event {\n",facName
);
205 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
206 fprintf(fp
,"\t%s", ((event
*)(fac
->events
.array
[pos
]))->name
);
207 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
209 fprintf(fp
,"\n};\n\n\n");
211 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
212 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
213 *nbEvent
= fac
->events
.position
;
217 /*****************************************************************************
219 * printStruct : Generic struct printing function
221 * fp : file to be written to
222 * len : number of fields
223 * array : array of field info
224 * name : basic struct name
225 * facName : name of facility
226 * whichTypeFirst : struct or array/sequence first
227 * hasStrSeq : string or sequence present?
228 * structCount : struct postfix
229 ****************************************************************************/
232 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
233 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
)
238 type_descriptor
* td
;
240 for (pos
= 0; pos
< len
; pos
++) {
241 fld
= (field
*)array
[pos
];
243 if( td
->type
!= STRING
&& td
->type
!= SEQUENCE
&&
245 if (*whichTypeFirst
== 0) {
246 *whichTypeFirst
= 1; //struct first
251 fprintf(fp
,"struct %s_%s",name
, facName
);
253 fprintf(fp
, "_%d {\n",++*structCount
);
258 fprintf(fp
, "\t%s %s; /* %s */\n",
259 getTypeStr(td
),fld
->name
,fld
->description
);
261 if (*whichTypeFirst
== 0) {
262 //string or sequence or array first
267 fprintf(fp
,"} __attribute__ ((packed));\n\n");
274 fprintf(fp
,"} __attribute__ ((packed));\n\n");
279 /*****************************************************************************
281 * generateHfile : Create the typedefs
283 * fp : file to be written to
284 ****************************************************************************/
286 generateTypeDefs(FILE * fp
)
290 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
292 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
293 type_descriptor
* type
=
294 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
295 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
296 "", type
->type_name
, &tmp
, &tmp
, NULL
);
297 fprintf(fp
, "typedef struct _%s %s;\n\n",
298 type
->type_name
, type
->type_name
);
303 /*****************************************************************************
305 * generateEnumDefinition: generate enum definition if it exists
307 * fp : file to be written to
309 ****************************************************************************/
310 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
313 fprintf(fp
,"enum {\n");
314 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
315 fprintf(fp
,"\t%s", type
->labels
.array
[pos
]);
316 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
317 if(type
->labels_description
.array
[pos
] != NULL
)
318 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
322 fprintf(fp
,"};\n\n\n");
325 /*****************************************************************************
327 * generateStrucTFunc: output structure and function to .h file
329 * fp : file to be written to
330 * facName : name of facility
331 ****************************************************************************/
332 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
335 type_descriptor
* td
;
337 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
339 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
340 ev
= (event
*) fac
->events
.array
[pos
];
341 //yxx if(ev->nested)continue;
342 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",ev
->name
);
343 if(ev
->type
== 0){ // event without type
344 fprintf(fp
,"static inline void trace_%s_%s(void){\n",facName
,ev
->name
);
345 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, 0, NULL);\n",facName
,checksum
,ev
->name
);
346 fprintf(fp
,"};\n\n\n");
350 //if fields contain enum, print out enum definition
351 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
352 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
353 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
356 //default: no string, array or sequence in the event
361 //structure for kernel
362 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
363 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
);
365 //trace function : function name and parameters
368 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
369 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
370 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
372 if(td
->type
== ARRAY
){
373 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
374 }else if(td
->type
== STRING
){
375 fprintf(fp
,"short int strLength_%d, %s * %s",++strCount
, getTypeStr(td
), fld
->name
);
376 }else if(td
->type
== SEQUENCE
){
377 fprintf(fp
,"%s seqLength_%d, %s * %s",uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
378 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
379 if(pos1
!= ev
->type
->fields
.position
-1)fprintf(fp
,", ");
383 //length of buffer : length of all structures
384 fprintf(fp
,"\tint bufLength = ");
385 for(pos1
=0;pos1
<structCount
;pos1
++){
386 fprintf(fp
,"sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
387 if(pos1
!= structCount
-1) fprintf(fp
," + ");
390 //length of buffer : length of all arrays, sequences and strings
394 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
395 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
397 if(td
->type
== SEQUENCE
|| td
->type
==STRING
||td
->type
==ARRAY
){
398 if(structCount
|| flag
> 0) fprintf(fp
," + ");
399 if(td
->type
== SEQUENCE
) fprintf(fp
,"sizeof(%s) + sizeof(%s) * seqLength_%d",uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
400 else if(td
->type
==STRING
) fprintf(fp
,"strLength_%d + 1", ++strCount
);
401 else if(td
->type
==ARRAY
) fprintf(fp
,"sizeof(%s) * %d", getTypeStr(td
),td
->size
);
402 if(structCount
== 0) flag
= 1;
408 fprintf(fp
,"\tchar buff[bufLength];\n");
410 //declare a char pointer if needed
411 if(structCount
+ hasStrSeq
> 1) fprintf(fp
,"\tchar * ptr = buff;\n");
413 //allocate memory for new struct and initialize it
414 if(whichTypeFirst
== 1){ //struct first
415 for(pos1
=0;pos1
<structCount
;pos1
++){
416 if(pos1
==0) fprintf(fp
,"\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",ev
->name
, facName
,ev
->name
, facName
);
417 else fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
419 }else if(whichTypeFirst
== 2){
420 for(pos1
=0;pos1
<structCount
;pos1
++)
421 fprintf(fp
,"\tstruct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
425 if(structCount
) fprintf(fp
,"\t//initialize structs\n");
428 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
429 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
431 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
435 if(structCount
> 1) fprintf(fp
,"\n");
437 if(structCount
== 1 && whichTypeFirst
== 1) fprintf(fp
, "\t__1->%s = %s;\n",fld
->name
,fld
->name
);
438 else fprintf(fp
, "\t__%d.%s = %s;\n",structCount
,fld
->name
,fld
->name
);
441 if(structCount
) fprintf(fp
,"\n");
443 //set ptr to the end of first struct if needed;
444 if(whichTypeFirst
== 1 && structCount
+ hasStrSeq
> 1){
445 fprintf(fp
,"\n\t//set ptr to the end of the first struct\n");
446 fprintf(fp
,"\tptr += sizeof(struct %s_%s_1);\n\n",ev
->name
, facName
);
449 //copy struct, sequence and string to buffer
454 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
455 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
457 if(td
->type
!= STRING
&& td
->type
!= SEQUENCE
&& td
->type
!= ARRAY
){
458 if(flag
== 0) structCount
++;
460 if((structCount
> 1 || whichTypeFirst
== 2) && flag
== 1){
461 fprintf(fp
,"\t//copy struct to buffer\n");
462 fprintf(fp
,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",structCount
, ev
->name
, facName
,structCount
);
463 fprintf(fp
,"\tptr += sizeof(struct %s_%s_%d);\n\n",ev
->name
, facName
,structCount
);
465 }else if(td
->type
== SEQUENCE
){
467 fprintf(fp
,"\t//copy sequence length and sequence to buffer\n");
468 fprintf(fp
,"\t*ptr = seqLength_%d;\n",++seqCount
);
469 fprintf(fp
,"\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
470 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * seqLength_%d);\n",fld
->name
, getTypeStr(td
), seqCount
);
471 fprintf(fp
,"\tptr += sizeof(%s) * seqLength_%d;\n\n",getTypeStr(td
), seqCount
);
472 }else if(td
->type
==STRING
){
474 fprintf(fp
,"\t//copy string to buffer\n");
475 fprintf(fp
,"\tif(strLength_%d > 0){\n",++strCount
);
476 fprintf(fp
,"\t\tmemcpy(ptr, %s, strLength_%d + 1);\n", fld
->name
, strCount
);
477 fprintf(fp
,"\t\tptr += strLength_%d + 1;\n",strCount
);
478 fprintf(fp
,"\t}else{\n");
479 fprintf(fp
,"\t\t*ptr = '\\0';\n");
480 fprintf(fp
,"\t\tptr += 1;\n");
481 fprintf(fp
,"\t}\n\n");
482 }else if(td
->type
==ARRAY
){
484 fprintf(fp
,"\t//copy array to buffer\n");
485 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n", fld
->name
, getTypeStr(td
), td
->size
);
486 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n",getTypeStr(td
), td
->size
);
489 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
491 //call trace function
492 fprintf(fp
,"\n\t//call trace function\n");
493 fprintf(fp
,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName
,checksum
,ev
->name
);
494 fprintf(fp
,"};\n\n\n");
499 /*****************************************************************************
501 * getTypeStr : generate type string
503 * td : a type descriptor
505 * char * : type string
506 ****************************************************************************/
507 char * getTypeStr(type_descriptor
* td
){
508 type_descriptor
* t
;
512 return intOutputTypes
[td
->size
];
514 return uintOutputTypes
[td
->size
];
520 return "unsigned long";
528 return floatOutputTypes
[td
->size
];
532 return uintOutputTypes
[td
->size
];
538 return intOutputTypes
[t
->size
];
540 return uintOutputTypes
[t
->size
];
546 return "unsigned long";
554 return floatOutputTypes
[t
->size
];
558 return uintOutputTypes
[t
->size
];
560 error_callback(NULL
,"Nested struct is not supportted");
564 case STRUCT
: //for now we do not support nested struct
565 error_callback(NULL
,"Nested struct is not supportted");
568 error_callback(NULL
,"No type information");
574 /*****************************************************************************
576 * generateLoaderfile: generate a facility loaded .h file
578 * fp : file to be written to
579 * facName : name of facility
580 * nbEvent : number of events in the facility
581 * checksum : checksum for the facility
582 ****************************************************************************/
583 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
584 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
585 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
586 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
587 fprintf(fp
,"#include <linux/module.h>\n\n", facName
, checksum
);
588 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
590 fprintf(fp
,"EXPORT_SYMBOL(ltt_facility_%s_%X);\n\n",facName
, checksum
);
591 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\tltt_facility_%s_%X\n",
593 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t0x%X\n", checksum
);
594 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\"%s\"\n", facName
);
595 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t%d\n\n", nbEvent
);
596 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
This page took 0.043238 seconds and 4 git commands to generate.