fix multiple enums
[lttv.git] / genevent / genevent.c
CommitLineData
3888436c 1/*
2
3genevent.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
8
9This 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
11the Free Software Foundation; version 2 of the License.
12
13This 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.
17
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
21*/
22
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.
26
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
30 definitions.
31
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. */
36
37#include <stdlib.h>
38#include <string.h>
31cbc5d3 39#include <ctype.h>
3888436c 40#include <stdio.h>
41#include <stdarg.h>
42#include <linux/errno.h>
43
44
45#include "parser.h"
46#include "genevent.h"
47
48/* Named types may be referenced from anywhere */
49
50facility * fac;
51
52int main(int argc, char** argv)
53{
54 char *token;
55 parse_file in;
56 char buffer[BUFFER_SIZE];
57 int i;
58
59 if(argc < 2){
60 printf("At least one event definition file is needed\n");
61 exit(1);
62 }
63
64 in.buffer = buffer;
65 in.error = error_callback;
66
67 for(i = 1 ; i < argc ; i++) {
68 in.lineno = 0;
69 in.name = allocAndCopy(argv[i]);
70
71 in.fp = fopen(in.name, "r");
72 if(!in.fp ){
73 in.error(&in,"cannot open facility input file");
74 }
75
76 while(1){
77 token = getToken(&in);
78 if(in.type == ENDFILE) break;
79
80 if(strcmp(token, "<")) in.error(&in,"not a facility file");
81 token = getName(&in);
82
83 if(strcmp("facility",token) == 0) {
31cbc5d3 84 fac = memAlloc(sizeof(facility));
85 fac->name = NULL;
86 fac->description = NULL;
87 sequence_init(&(fac->events));
88 table_init(&(fac->named_types));
89 sequence_init(&(fac->unnamed_types));
90
91 parseFacility(&in, fac);
92
93 //check if any namedType is not defined
94 checkNamedTypesImplemented(&fac->named_types);
95 }
96 else in.error(&in,"facility token was expected");
3888436c 97
98 generateFile(argv[i]);
99
100 free(fac->name);
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);
108 free(fac);
109 }
110
111 free(in.name);
112 fclose(in.fp);
113
114 }
115 return 0;
116}
117
118
119/*****************************************************************************
120 *Function name
121 * generateFile : generate .c and .h file
122 *Input Params
123 * name : name of event definition file
124 ****************************************************************************/
125void generateFile(char *name){
6d387597 126 char *loadName, *hName, *tmp, *tmp2;
127 FILE * lFp, *hFp;
3888436c 128 int nbEvent;
129 unsigned long checksum=0;
130
131 //remove .xml if it exists
132 tmp = &name[strlen(name)-4];
133 if(strcmp(tmp, ".xml") == 0){
134 *tmp = '\0';
135 }
136
137 tmp = strrchr(name,'/');
138 if(tmp){
139 tmp++;
140 }else{
141 tmp = name;
142 }
6d387597 143
144 loadName = appendString("ltt-facility-loader-", tmp);
145 tmp2 = appendString(loadName,".h");
146 free(loadName);
147 loadName = tmp2;
148 hName = appendString("ltt-facility-", tmp);
149 tmp2 = appendString(hName,".h");
150 free(hName);
151 hName = tmp2;
152 lFp = fopen(loadName,"w");
153 if(!lFp){
154 printf("Cannot open the file : %s\n",loadName);
3888436c 155 exit(1);
156 }
157
158 hFp = fopen(hName,"w");
159 if(!hFp){
160 printf("Cannot open the file : %s\n",hName);
161 exit(1);
162 }
163
6d387597 164 free(loadName);
3888436c 165 free(hName);
166
167 generateChecksum(fac->name, &checksum, &(fac->events));
168
169 /* generate .h file, event enumeration then structures and functions */
31cbc5d3 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);
3888436c 176
6d387597 177 /* generate .h file, calls to register the facility at init time */
8c6ca411 178 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
3888436c 179
180 fclose(hFp);
6d387597 181 fclose(lFp);
3888436c 182}
183
184
185/*****************************************************************************
186 *Function name
187 * generateEnumEvent : output event enum to .h file
188 *Input Params
189 * fp : file to be written to
190 * facName : name of facility
191 *Output Params
192 * nbEvent : number of events in the facility
193 ****************************************************************************/
31cbc5d3 194void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
3888436c 195 int pos = 0;
196
31cbc5d3 197 fprintf(fp,"#include <linux/ltt-log.h>\n\n");
3888436c 198
199 fprintf(fp,"/**** facility handle ****/\n\n");
44cac8a9 200 fprintf(fp,"extern trace_facility_t ltt_facility_%s_%X;\n",facName, checksum);
201 fprintf(fp,"extern trace_facility_t ltt_facility_%s;\n\n\n",facName, checksum);
3888436c 202
203 fprintf(fp,"/**** event type ****/\n\n");
204 fprintf(fp,"enum %s_event {\n",facName);
205
206 for(pos = 0; pos < fac->events.position;pos++) {
31cbc5d3 207 fprintf(fp,"\t%s", ((event *)(fac->events.array[pos]))->name);
3888436c 208 if(pos != fac->events.position-1) fprintf(fp,",\n");
209 }
210 fprintf(fp,"\n};\n\n\n");
211
212 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
213 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
214 *nbEvent = fac->events.position;
215}
216
217
31cbc5d3 218/*****************************************************************************
219 *Function name
220 * printStruct : Generic struct printing function
221 *Input Params
222 * fp : file to be written to
223 * len : number of fields
224 * array : array of field info
225 * name : basic struct name
226 * facName : name of facility
227 * whichTypeFirst : struct or array/sequence first
228 * hasStrSeq : string or sequence present?
229 * structCount : struct postfix
230 ****************************************************************************/
cb1eb7ce 231
31cbc5d3 232static void
233printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
234 int * whichTypeFirst, int * hasStrSeq, int * structCount)
235{
236 int flag = 0;
237 int pos;
238 field * fld;
239 type_descriptor * td;
240
241 for (pos = 0; pos < len; pos++) {
242 fld = (field *)array[pos];
243 td = fld->type;
244 if( td->type != STRING && td->type != SEQUENCE &&
cb1eb7ce 245 td->type != ARRAY) {
31cbc5d3 246 if (*whichTypeFirst == 0) {
247 *whichTypeFirst = 1; //struct first
248 }
249 if (flag == 0) {
250 flag = 1;
251
cb1eb7ce 252 fprintf(fp,"struct %s_%s",name, facName);
253 if (structCount) {
254 fprintf(fp, "_%d {\n",++*structCount);
255 } else {
256 fprintf(fp, " {\n");
257 }
31cbc5d3 258 }
cb1eb7ce 259 fprintf(fp, "\t%s %s; /* %s */\n",
260 getTypeStr(td),fld->name,fld->description );
31cbc5d3 261 } else {
cb1eb7ce 262 if (*whichTypeFirst == 0) {
31cbc5d3 263 //string or sequence or array first
cb1eb7ce 264 *whichTypeFirst = 2;
265 }
266 (*hasStrSeq)++;
267 if(flag) {
268 fprintf(fp,"} __attribute__ ((packed));\n\n");
269 }
270 flag = 0;
31cbc5d3 271 }
272 }
273
274 if(flag) {
275 fprintf(fp,"} __attribute__ ((packed));\n\n");
276 }
277}
278
279
280/*****************************************************************************
281 *Function name
282 * generateHfile : Create the typedefs
283 *Input Params
284 * fp : file to be written to
285 ****************************************************************************/
286void
287generateTypeDefs(FILE * fp)
288{
289 int pos, tmp = 1;
290
291 fprintf(fp, "/**** Basic Type Definitions ****/\n\n");
292
293 for (pos = 0; pos < fac->named_types.values.position; pos++) {
294 type_descriptor * type =
295 (type_descriptor*)fac->named_types.values.array[pos];
296 printStruct(fp, type->fields.position, type->fields.array,
297 "", type->type_name, &tmp, &tmp, NULL);
298 fprintf(fp, "typedef struct _%s %s;\n\n",
299 type->type_name, type->type_name);
300 }
301}
302
303
3888436c 304/*****************************************************************************
305 *Function name
306 * generateEnumDefinition: generate enum definition if it exists
307 *Input Params
308 * fp : file to be written to
309 * fHead : enum type
310 ****************************************************************************/
311void generateEnumDefinition(FILE * fp, type_descriptor * type){
312 int pos;
313
44cac8a9 314 if(type->already_printed) return;
315
3888436c 316 fprintf(fp,"enum {\n");
317 for(pos = 0; pos < type->labels.position; pos++){
31cbc5d3 318 fprintf(fp,"\t%s", type->labels.array[pos]);
8c6ca411 319 if (pos != type->labels.position - 1) fprintf(fp,",");
320 if(type->labels_description.array[pos] != NULL)
321 fprintf(fp,"\t/* %s */\n",type->labels_description.array[pos]);
322 else
323 fprintf(fp,"\n");
3888436c 324 }
8c6ca411 325 fprintf(fp,"};\n\n\n");
44cac8a9 326
327 type->already_printed = 1;
3888436c 328}
329
330/*****************************************************************************
331 *Function name
332 * generateStrucTFunc: output structure and function to .h file
333 *Input Params
334 * fp : file to be written to
335 * facName : name of facility
336 ****************************************************************************/
31cbc5d3 337void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
3888436c 338 event * ev;
339 field * fld;
340 type_descriptor * td;
341 int pos, pos1;
342 int hasStrSeq, flag, structCount, seqCount,strCount, whichTypeFirst=0;
343
344 for(pos = 0; pos < fac->events.position; pos++){
345 ev = (event *) fac->events.array[pos];
346 //yxx if(ev->nested)continue;
347 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",ev->name);
348 if(ev->type == 0){ // event without type
349 fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
31cbc5d3 350 fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, 0, NULL);\n",facName,checksum,ev->name);
3888436c 351 fprintf(fp,"};\n\n\n");
352 continue;
353 }
354
355 //if fields contain enum, print out enum definition
356 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
357 fld = (field *)ev->type->fields.array[pos1];
358 if(fld->type->type == ENUM) generateEnumDefinition(fp, fld->type);
359 }
360
361 //default: no string, array or sequence in the event
362 hasStrSeq = 0;
363 whichTypeFirst = 0;
3888436c 364 structCount = 0;
31cbc5d3 365
366 //structure for kernel
367 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
368 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount);
3888436c 369
370 //trace function : function name and parameters
371 seqCount = 0;
372 strCount = 0;
373 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
374 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
375 fld = (field *)ev->type->fields.array[pos1];
376 td = fld->type;
377 if(td->type == ARRAY ){
378 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
379 }else if(td->type == STRING){
380 fprintf(fp,"short int strLength_%d, %s * %s",++strCount, getTypeStr(td), fld->name);
381 }else if(td->type == SEQUENCE){
382 fprintf(fp,"%s seqLength_%d, %s * %s",uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
383 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
384 if(pos1 != ev->type->fields.position -1)fprintf(fp,", ");
385 }
386 fprintf(fp,"){\n");
387
388 //length of buffer : length of all structures
31cbc5d3 389 fprintf(fp,"\tint bufLength = ");
3888436c 390 for(pos1=0;pos1<structCount;pos1++){
391 fprintf(fp,"sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
392 if(pos1 != structCount-1) fprintf(fp," + ");
393 }
394
395 //length of buffer : length of all arrays, sequences and strings
396 seqCount = 0;
397 strCount = 0;
398 flag = 0;
399 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
400 fld = (field *)ev->type->fields.array[pos1];
401 td = fld->type;
402 if(td->type == SEQUENCE || td->type==STRING ||td->type==ARRAY){
403 if(structCount || flag > 0) fprintf(fp," + ");
404 if(td->type == SEQUENCE) fprintf(fp,"sizeof(%s) + sizeof(%s) * seqLength_%d",uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
405 else if(td->type==STRING) fprintf(fp,"strLength_%d + 1", ++strCount);
406 else if(td->type==ARRAY) fprintf(fp,"sizeof(%s) * %d", getTypeStr(td),td->size);
407 if(structCount == 0) flag = 1;
408 }
409 }
410 fprintf(fp,";\n");
411
412 //allocate buffer
31cbc5d3 413 fprintf(fp,"\tchar buff[bufLength];\n");
3888436c 414
415 //declare a char pointer if needed
31cbc5d3 416 if(structCount + hasStrSeq > 1) fprintf(fp,"\tchar * ptr = buff;\n");
3888436c 417
418 //allocate memory for new struct and initialize it
419 if(whichTypeFirst == 1){ //struct first
420 for(pos1=0;pos1<structCount;pos1++){
31cbc5d3 421 if(pos1==0) fprintf(fp,"\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",ev->name, facName,ev->name, facName);
422 else fprintf(fp,"\tstruct %s_%s_%d __%d;\n",ev->name, facName,pos1+1,pos1+1);
3888436c 423 }
424 }else if(whichTypeFirst == 2){
425 for(pos1=0;pos1<structCount;pos1++)
31cbc5d3 426 fprintf(fp,"\tstruct %s_%s_%d __%d;\n",ev->name, facName,pos1+1,pos1+1);
3888436c 427 }
428 fprintf(fp,"\n");
429
31cbc5d3 430 if(structCount) fprintf(fp,"\t//initialize structs\n");
3888436c 431 flag = 0;
432 structCount = 0;
433 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
434 fld = (field *)ev->type->fields.array[pos1];
435 td = fld->type;
436 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
437 if(flag == 0){
438 flag = 1;
439 structCount++;
440 if(structCount > 1) fprintf(fp,"\n");
441 }
31cbc5d3 442 if(structCount == 1 && whichTypeFirst == 1) fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
443 else fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
3888436c 444 }else flag = 0;
445 }
446 if(structCount) fprintf(fp,"\n");
447
448 //set ptr to the end of first struct if needed;
449 if(whichTypeFirst == 1 && structCount + hasStrSeq > 1){
31cbc5d3 450 fprintf(fp,"\n\t//set ptr to the end of the first struct\n");
451 fprintf(fp,"\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
3888436c 452 }
453
454 //copy struct, sequence and string to buffer
455 seqCount = 0;
456 strCount = 0;
457 flag = 0;
458 structCount = 0;
459 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
460 fld = (field *)ev->type->fields.array[pos1];
461 td = fld->type;
462 if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
463 if(flag == 0) structCount++;
464 flag++;
465 if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
31cbc5d3 466 fprintf(fp,"\t//copy struct to buffer\n");
467 fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",structCount, ev->name, facName,structCount);
468 fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",ev->name, facName,structCount);
3888436c 469 }
470 }else if(td->type == SEQUENCE){
471 flag = 0;
31cbc5d3 472 fprintf(fp,"\t//copy sequence length and sequence to buffer\n");
473 fprintf(fp,"\t*ptr = seqLength_%d;\n",++seqCount);
474 fprintf(fp,"\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
475 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * seqLength_%d);\n",fld->name, getTypeStr(td), seqCount);
476 fprintf(fp,"\tptr += sizeof(%s) * seqLength_%d;\n\n",getTypeStr(td), seqCount );
3888436c 477 }else if(td->type==STRING){
478 flag = 0;
31cbc5d3 479 fprintf(fp,"\t//copy string to buffer\n");
480 fprintf(fp,"\tif(strLength_%d > 0){\n",++strCount);
481 fprintf(fp,"\t\tmemcpy(ptr, %s, strLength_%d + 1);\n", fld->name, strCount);
482 fprintf(fp,"\t\tptr += strLength_%d + 1;\n",strCount);
483 fprintf(fp,"\t}else{\n");
484 fprintf(fp,"\t\t*ptr = '\\0';\n");
485 fprintf(fp,"\t\tptr += 1;\n");
486 fprintf(fp,"\t}\n\n");
3888436c 487 }else if(td->type==ARRAY){
488 flag = 0;
31cbc5d3 489 fprintf(fp,"\t//copy array to buffer\n");
490 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n", fld->name, getTypeStr(td), td->size);
491 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n",getTypeStr(td), td->size);
3888436c 492 }
493 }
494 if(structCount + seqCount > 1) fprintf(fp,"\n");
495
496 //call trace function
31cbc5d3 497 fprintf(fp,"\n\t//call trace function\n");
498 fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
3888436c 499 fprintf(fp,"};\n\n\n");
500 }
501
502}
503
504/*****************************************************************************
505 *Function name
506 * getTypeStr : generate type string
507 *Input Params
508 * td : a type descriptor
509 *Return Values
510 * char * : type string
511 ****************************************************************************/
512char * getTypeStr(type_descriptor * td){
513 type_descriptor * t ;
514
515 switch(td->type){
516 case INT:
517 return intOutputTypes[td->size];
518 case UINT:
519 return uintOutputTypes[td->size];
31cbc5d3 520 case POINTER:
521 return "void *";
522 case LONG:
523 return "long";
524 case ULONG:
525 return "unsigned long";
526 case SIZE_T:
527 return "size_t";
528 case SSIZE_T:
529 return "ssize_t";
530 case OFF_T:
531 return "off_t";
3888436c 532 case FLOAT:
533 return floatOutputTypes[td->size];
534 case STRING:
535 return "char";
536 case ENUM:
537 return uintOutputTypes[td->size];
538 case ARRAY:
539 case SEQUENCE:
540 t = td->nested_type;
541 switch(t->type){
542 case INT:
31cbc5d3 543 return intOutputTypes[t->size];
3888436c 544 case UINT:
31cbc5d3 545 return uintOutputTypes[t->size];
546 case POINTER:
547 return "void *";
548 case LONG:
549 return "long";
550 case ULONG:
551 return "unsigned long";
552 case SIZE_T:
553 return "size_t";
554 case SSIZE_T:
555 return "ssize_t";
556 case OFF_T:
557 return "off_t";
3888436c 558 case FLOAT:
31cbc5d3 559 return floatOutputTypes[t->size];
3888436c 560 case STRING:
31cbc5d3 561 return "char";
3888436c 562 case ENUM:
31cbc5d3 563 return uintOutputTypes[t->size];
3888436c 564 default :
31cbc5d3 565 error_callback(NULL,"Nested struct is not supportted");
566 break;
3888436c 567 }
568 break;
569 case STRUCT: //for now we do not support nested struct
570 error_callback(NULL,"Nested struct is not supportted");
571 break;
572 default:
573 error_callback(NULL,"No type information");
574 break;
575 }
576 return NULL;
577}
578
579/*****************************************************************************
580 *Function name
6d387597 581 * generateLoaderfile: generate a facility loaded .h file
3888436c 582 *Input Params
583 * fp : file to be written to
584 * facName : name of facility
585 * nbEvent : number of events in the facility
586 * checksum : checksum for the facility
587 ****************************************************************************/
8c6ca411 588void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
589 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
590 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
591 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
592 fprintf(fp,"#include <linux/module.h>\n\n", facName, checksum);
44cac8a9 593 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
6d387597 594 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
595
44cac8a9 596 fprintf(fp,"EXPORT_SYMBOL(ltt_facility_%s);\n\n",facName, checksum);
6d387597 597 fprintf(fp,"EXPORT_SYMBOL(ltt_facility_%s_%X);\n\n",facName, checksum);
44cac8a9 598 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\tltt_facility_%s\n",
599 facName);
600 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\t\t\tltt_facility_%s_%X\n",
6d387597 601 facName, checksum);
602 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t0x%X\n", checksum);
603 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\"%s\"\n", facName);
604 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t%d\n\n", nbEvent);
8c6ca411 605 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
3888436c 606}
607
608
This page took 0.047577 seconds and 4 git commands to generate.