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. */
41 #include <linux/errno.h>
47 /* Named types may be referenced from anywhere */
51 int main(int argc
, char** argv
)
55 char buffer
[BUFFER_SIZE
];
59 printf("At least one event definition file is needed\n");
64 in
.error
= error_callback
;
66 for(i
= 1 ; i
< argc
; i
++) {
68 in
.name
= allocAndCopy(argv
[i
]);
70 in
.fp
= fopen(in
.name
, "r");
72 in
.error(&in
,"cannot open facility input file");
76 token
= getToken(&in
);
77 if(in
.type
== ENDFILE
) break;
79 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
82 if(strcmp("facility",token
) == 0) {
83 fac
= memAlloc(sizeof(facility
));
85 fac
->description
= NULL
;
86 sequence_init(&(fac
->events
));
87 table_init(&(fac
->named_types
));
88 sequence_init(&(fac
->unnamed_types
));
90 parseFacility(&in
, fac
);
92 //check if any namedType is not defined
93 checkNamedTypesImplemented(&fac
->named_types
);
94 }else in
.error(&in
,"facility token was expected");
96 generateFile(argv
[i
]);
99 free(fac
->description
);
100 freeEvents(&fac
->events
);
101 sequence_dispose(&fac
->events
);
102 freeNamedType(&fac
->named_types
);
103 table_dispose(&fac
->named_types
);
104 freeTypes(&fac
->unnamed_types
);
105 sequence_dispose(&fac
->unnamed_types
);
117 /*****************************************************************************
119 * generateFile : generate .c and .h file
121 * name : name of event definition file
122 ****************************************************************************/
123 void generateFile(char *name
){
124 char *cName
, *hName
, *tmp
;
127 unsigned long checksum
=0;
129 //remove .xml if it exists
130 tmp
= &name
[strlen(name
)-4];
131 if(strcmp(tmp
, ".xml") == 0){
135 tmp
= strrchr(name
,'/');
142 cName
= appendString(tmp
,".c");
143 hName
= appendString(tmp
,".h");
144 cFp
= fopen(cName
,"w");
146 printf("Cannot open the file : %s\n",cName
);
150 hFp
= fopen(hName
,"w");
152 printf("Cannot open the file : %s\n",hName
);
159 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
161 /* generate .h file, event enumeration then structures and functions */
162 generateEnumEvent(hFp
, fac
->name
, &nbEvent
);
163 generateStructFunc(hFp
, fac
->name
);
165 /* generate .c file, calls to register the facility at init time */
166 generateCfile(cFp
,fac
->name
,nbEvent
,checksum
);
173 /*****************************************************************************
175 * generateEnumEvent : output event enum to .h file
177 * fp : file to be written to
178 * facName : name of facility
180 * nbEvent : number of events in the facility
181 ****************************************************************************/
182 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
) {
185 //will be removed later
186 fprintf(fp
,"typedef unsigned int trace_facility_t;\n\n");
187 fprintf(fp
,"extern int trace_new(trace_facility_t fID, u8 eID, int length, char * buf);\n\n");
190 fprintf(fp
,"/**** facility handle ****/\n\n");
191 fprintf(fp
,"extern trace_facility_t facility_%s;\n\n\n",facName
);
193 fprintf(fp
,"/**** event type ****/\n\n");
194 fprintf(fp
,"enum %s_event {\n",facName
);
196 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
197 fprintf(fp
," %s", ((event
*)(fac
->events
.array
[pos
]))->name
);
198 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
200 fprintf(fp
,"\n};\n\n\n");
202 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
203 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
204 *nbEvent
= fac
->events
.position
;
208 /*****************************************************************************
210 * generateEnumDefinition: generate enum definition if it exists
212 * fp : file to be written to
214 ****************************************************************************/
215 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
218 fprintf(fp
,"enum {\n");
219 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
220 fprintf(fp
," %s", type
->labels
.array
[pos
]);
221 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",\n");
223 fprintf(fp
,"\n};\n\n\n");
226 /*****************************************************************************
228 * generateStrucTFunc: output structure and function to .h file
230 * fp : file to be written to
231 * facName : name of facility
232 ****************************************************************************/
233 void generateStructFunc(FILE * fp
, char * facName
){
236 type_descriptor
* td
;
238 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
240 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
241 ev
= (event
*) fac
->events
.array
[pos
];
242 //yxx if(ev->nested)continue;
243 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",ev
->name
);
244 if(ev
->type
== 0){ // event without type
245 fprintf(fp
,"static inline void trace_%s_%s(void){\n",facName
,ev
->name
);
246 fprintf(fp
," trace_new(facility_%s, %s, 0, NULL);\n",facName
,ev
->name
);
247 fprintf(fp
,"};\n\n\n");
251 //if fields contain enum, print out enum definition
252 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
253 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
254 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
257 //default: no string, array or sequence in the event
261 //structure for kernel
264 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
265 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
267 if( td
->type
!= STRING
&& td
->type
!= SEQUENCE
&& td
->type
!= ARRAY
){
268 if(whichTypeFirst
== 0) whichTypeFirst
= 1; //struct first
271 fprintf(fp
,"struct %s_%s_%d{\n",ev
->name
,facName
,++structCount
);
273 fprintf(fp
, " %s %s; /* %s */\n",getTypeStr(td
),fld
->name
,fld
->description
);
275 if(whichTypeFirst
== 0) whichTypeFirst
= 2; //string or sequence or array first
278 fprintf(fp
,"} __attribute__ ((packed));\n\n");
283 fprintf(fp
,"} __attribute__ ((packed));\n\n");
285 //trace function : function name and parameters
288 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
289 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
290 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
292 if(td
->type
== ARRAY
){
293 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
294 }else if(td
->type
== STRING
){
295 fprintf(fp
,"short int strLength_%d, %s * %s",++strCount
, getTypeStr(td
), fld
->name
);
296 }else if(td
->type
== SEQUENCE
){
297 fprintf(fp
,"%s seqLength_%d, %s * %s",uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
298 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
299 if(pos1
!= ev
->type
->fields
.position
-1)fprintf(fp
,", ");
303 //length of buffer : length of all structures
304 fprintf(fp
," int bufLength = ");
305 for(pos1
=0;pos1
<structCount
;pos1
++){
306 fprintf(fp
,"sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
307 if(pos1
!= structCount
-1) fprintf(fp
," + ");
310 //length of buffer : length of all arrays, sequences and strings
314 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
315 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
317 if(td
->type
== SEQUENCE
|| td
->type
==STRING
||td
->type
==ARRAY
){
318 if(structCount
|| flag
> 0) fprintf(fp
," + ");
319 if(td
->type
== SEQUENCE
) fprintf(fp
,"sizeof(%s) + sizeof(%s) * seqLength_%d",uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
320 else if(td
->type
==STRING
) fprintf(fp
,"strLength_%d + 1", ++strCount
);
321 else if(td
->type
==ARRAY
) fprintf(fp
,"sizeof(%s) * %d", getTypeStr(td
),td
->size
);
322 if(structCount
== 0) flag
= 1;
328 fprintf(fp
," char buff[bufLength];\n");
330 //declare a char pointer if needed
331 if(structCount
+ hasStrSeq
> 1) fprintf(fp
," char * ptr = buff;\n");
333 //allocate memory for new struct and initialize it
334 if(whichTypeFirst
== 1){ //struct first
335 for(pos1
=0;pos1
<structCount
;pos1
++){
336 if(pos1
==0) fprintf(fp
," struct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",ev
->name
, facName
,ev
->name
, facName
);
337 else fprintf(fp
," struct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
339 }else if(whichTypeFirst
== 2){
340 for(pos1
=0;pos1
<structCount
;pos1
++)
341 fprintf(fp
," struct %s_%s_%d __%d;\n",ev
->name
, facName
,pos1
+1,pos1
+1);
345 if(structCount
) fprintf(fp
," //initialize structs\n");
348 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
349 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
351 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
355 if(structCount
> 1) fprintf(fp
,"\n");
357 if(structCount
== 1 && whichTypeFirst
== 1) fprintf(fp
, " __1->%s = %s;\n",fld
->name
,fld
->name
);
358 else fprintf(fp
, " __%d.%s = %s;\n",structCount
,fld
->name
,fld
->name
);
361 if(structCount
) fprintf(fp
,"\n");
363 //set ptr to the end of first struct if needed;
364 if(whichTypeFirst
== 1 && structCount
+ hasStrSeq
> 1){
365 fprintf(fp
,"\n //set ptr to the end of the first struct\n");
366 fprintf(fp
," ptr += sizeof(struct %s_%s_1);\n\n",ev
->name
, facName
);
369 //copy struct, sequence and string to buffer
374 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
375 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
377 if(td
->type
!= STRING
&& td
->type
!= SEQUENCE
&& td
->type
!= ARRAY
){
378 if(flag
== 0) structCount
++;
380 if((structCount
> 1 || whichTypeFirst
== 2) && flag
== 1){
381 fprintf(fp
," //copy struct to buffer\n");
382 fprintf(fp
," memcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",structCount
, ev
->name
, facName
,structCount
);
383 fprintf(fp
," ptr += sizeof(struct %s_%s_%d);\n\n",ev
->name
, facName
,structCount
);
385 }else if(td
->type
== SEQUENCE
){
387 fprintf(fp
," //copy sequence length and sequence to buffer\n");
388 fprintf(fp
," *ptr = seqLength_%d;\n",++seqCount
);
389 fprintf(fp
," ptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
390 fprintf(fp
," memcpy(ptr, %s, sizeof(%s) * seqLength_%d);\n",fld
->name
, getTypeStr(td
), seqCount
);
391 fprintf(fp
," ptr += sizeof(%s) * seqLength_%d;\n\n",getTypeStr(td
), seqCount
);
392 }else if(td
->type
==STRING
){
394 fprintf(fp
," //copy string to buffer\n");
395 fprintf(fp
," if(strLength_%d > 0){\n",++strCount
);
396 fprintf(fp
," memcpy(ptr, %s, strLength_%d + 1);\n", fld
->name
, strCount
);
397 fprintf(fp
," ptr += strLength_%d + 1;\n",strCount
);
398 fprintf(fp
," }else{\n");
399 fprintf(fp
," *ptr = '\\0';\n");
400 fprintf(fp
," ptr += 1;\n");
401 fprintf(fp
," }\n\n");
402 }else if(td
->type
==ARRAY
){
404 fprintf(fp
," //copy array to buffer\n");
405 fprintf(fp
," memcpy(ptr, %s, sizeof(%s) * %d);\n", fld
->name
, getTypeStr(td
), td
->size
);
406 fprintf(fp
," ptr += sizeof(%s) * %d;\n\n",getTypeStr(td
), td
->size
);
409 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
411 //call trace function
412 fprintf(fp
,"\n //call trace function\n");
413 fprintf(fp
," trace_new(facility_%s, %s, bufLength, buff);\n",facName
,ev
->name
);
414 fprintf(fp
,"};\n\n\n");
419 /*****************************************************************************
421 * getTypeStr : generate type string
423 * td : a type descriptor
425 * char * : type string
426 ****************************************************************************/
427 char * getTypeStr(type_descriptor
* td
){
428 type_descriptor
* t
;
432 return intOutputTypes
[td
->size
];
434 return uintOutputTypes
[td
->size
];
436 return floatOutputTypes
[td
->size
];
440 return uintOutputTypes
[td
->size
];
446 return intOutputTypes
[t
->size
];
448 return uintOutputTypes
[t
->size
];
450 return floatOutputTypes
[t
->size
];
454 return uintOutputTypes
[t
->size
];
456 error_callback(NULL
,"Nested struct is not supportted");
460 case STRUCT
: //for now we do not support nested struct
461 error_callback(NULL
,"Nested struct is not supportted");
464 error_callback(NULL
,"No type information");
470 /*****************************************************************************
472 * generateCfile : generate a .c file
474 * fp : file to be written to
475 * facName : name of facility
476 * nbEvent : number of events in the facility
477 * checksum : checksum for the facility
478 ****************************************************************************/
479 void generateCfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
){
480 //will be removed later
481 fprintf(fp
,"typedef unsigned int trace_facility_t;\n\n");
483 fprintf(fp
,"static unsigned long checksum = %lu;\n\n",checksum
);
484 fprintf(fp
,"/* facility handle */\n");
485 fprintf(fp
,"trace_facility_t facility_%s;\n\n",facName
);
487 fprintf(fp
,"static void __init facility_%s_init(){\n",facName
);
488 fprintf(fp
," facility_%s = trace_register_facility_by_checksum(\"%s\", checksum,%d);\n",facName
,facName
,nbEvent
);
491 fprintf(fp
,"static void __exit facility_%s_exit(){\n",facName
);
494 fprintf(fp
,"module_init(facility_%s_init);\n",facName
);
495 fprintf(fp
,"module_exit(facility_%s_exit);\n",facName
);
This page took 0.046797 seconds and 4 git commands to generate.