1 /******************************************************************************
4 * Event generator. XML to logging C code converter.
9 * Will generate ltt-facility-name.h, ltt-facility-id-name.h
10 * ltt-facility-loader-name.c, ltt-facility-loader-name.h
11 * in the current directory.
15 * - C types : struct, union, enum, basic types.
16 * - Architectures : LP32, ILP32, ILP64, LLP64, LP64.
18 * Additionnal structures supported :
19 * - embedded variable size strings
20 * - embedded variable size arrays
21 * - embedded variable size sequences
25 * enums are limited to integer type, as this is what is used in C. Note,
26 * however, that ISO/IEC 9899:TC2 specify that the type of enum can be char,
27 * unsigned int or int. This is implementation defined (compiler). That's why we
28 * add a check for sizeof enum.
31 * Because of archtecture defined type sizes, we need to ask for ltt_align
32 * (which gives the alignment) by passing basic types, not their actual sizes.
33 * It's up to ltt_align to determine sizes of types.
36 * http://www.usenix.org/publications/login/standards/10.data.html
37 * (Andrew Josey <a.josey@opengroup.org>) :
39 * Data Type LP32 ILP32 ILP64 LLP64 LP64
41 * short 16 16 16 16 16
45 * long long (int64) 64
46 * pointer 32 32 64 64 64
48 * With these constraints :
49 * sizeof(char) <= sizeof(short) <= sizeof(int)
50 * <= sizeof(long) = sizeof(size_t)
52 * and therefore sizeof(long) <= sizeof(pointer) <= sizeof(size_t)
54 * Which means we only have to remember which is the biggest type in a structure
55 * to know the structure's alignment.
62 #include <sys/types.h>
77 /* Debugging printf */
79 #define dprintf(...) \
81 printf(__FILE__ ",%u,%s: ",\
92 void print_tabs(unsigned int tabs
, FILE *fd
)
94 for(unsigned int i
= 0; i
<tabs
;i
++)
98 /* Type size checking */
99 /* Uses #error in the generated code to signal error and stop the compiler */
100 int print_check(int fd
);
104 int print_types(int fd
);
108 int print_events(int fd
);
113 * Copied from construct_types_and_fields in LTTV facility.c */
115 int print_type(type_descriptor_t
* td
, FILE *fd
, unsigned int tabs
,
116 char *nest_name
, char *field_name
)
118 char basename
[PATH_MAX
];
119 unsigned int basename_len
= 0;
121 strcpy(basename
, nest_name
);
122 basename_len
= strlen(basename
);
124 /* For a named type, we use the type_name directly */
125 if(td
->type_name
!= NULL
) {
126 strncpy(basename
, td
->type_name
, PATH_MAX
);
127 basename_len
= strlen(basename
);
129 /* For a unnamed type, there must be a field name */
130 if((basename_len
!= 0)
131 && (basename
[basename_len
-1] != '_')
132 && (field_name
[0] != '\0')) {
133 strncat(basename
, "_", PATH_MAX
- basename_len
);
134 basename_len
= strlen(basename
);
136 strncat(basename
, field_name
, PATH_MAX
- basename_len
);
141 fprintf(fd
, "%s", intOutputTypes
[getSizeindex(td
->size
)]);
144 fprintf(fd
, "%s", uintOutputTypes
[getSizeindex(td
->size
)]);
147 fprintf(fd
, "signed char");
150 fprintf(fd
, "unsigned char");
153 fprintf(fd
, "short");
156 fprintf(fd
, "unsigned short");
162 fprintf(fd
, "unsigned int");
165 fprintf(fd
, "%s", floatOutputTypes
[getSizeindex(td
->size
)]);
168 fprintf(fd
, "void *");
174 fprintf(fd
, "unsigned long");
177 fprintf(fd
, "size_t");
180 fprintf(fd
, "ssize_t");
183 fprintf(fd
, "off_t");
186 fprintf(fd
, "char *");
189 fprintf(fd
, "enum lttng_%s", basename
);
192 fprintf(fd
, "lttng_array_%s", basename
);
195 fprintf(fd
, "lttng_sequence_%s", basename
);
198 fprintf(fd
, "struct lttng_%s", basename
);
201 fprintf(fd
, "union lttng_%s", basename
);
204 printf("print_type : unknown type\n");
211 /* print type declaration.
213 * Copied from construct_types_and_fields in LTTV facility.c */
215 int print_type_declaration(type_descriptor_t
* td
, FILE *fd
, unsigned int tabs
,
216 char *nest_name
, char *field_name
)
218 char basename
[PATH_MAX
];
219 unsigned int basename_len
= 0;
221 strncpy(basename
, nest_name
, PATH_MAX
);
222 basename_len
= strlen(basename
);
224 /* For a named type, we use the type_name directly */
225 if(td
->type_name
!= NULL
) {
226 strncpy(basename
, td
->type_name
, PATH_MAX
);
227 basename_len
= strlen(basename
);
229 /* For a unnamed type, there must be a field name, except for
231 if((basename_len
!= 0)
232 && (basename
[basename_len
-1] != '_'
233 && (field_name
[0] != '\0'))) {
234 strncat(basename
, "_", PATH_MAX
- basename_len
);
235 basename_len
= strlen(basename
);
237 strncat(basename
, field_name
, PATH_MAX
- basename_len
);
242 fprintf(fd
, "enum lttng_%s", basename
);
244 for(unsigned int i
=0;i
<td
->labels
.position
;i
++){
246 fprintf(fd
, "LTTNG_%s", ((char*)(td
->labels
.array
[i
])));
254 dprintf("%s\n", basename
);
255 assert(td
->size
>= 0);
256 if(td
->nested_type
->type_name
== NULL
) {
257 /* Not a named nested type : we must print its declaration first */
258 if(print_type_declaration(td
->nested_type
,
259 fd
, 0, basename
, "")) return 1;
261 fprintf(fd
, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename
,
263 if(print_type(td
->nested_type
, fd
, tabs
, basename
, "")) return 1;
264 fprintf(fd
, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename
,
269 if(td
->nested_type
->type_name
== NULL
) {
270 /* Not a named nested type : we must print its declaration first */
271 if(print_type_declaration(td
->nested_type
,
272 fd
, 0, basename
, "")) return 1;
274 fprintf(fd
, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n",
277 fprintf(fd
, "struct lttng_sequence_%s", basename
);
280 fprintf(fd
, "unsigned int len;\n");
282 if(print_type(td
->nested_type
, fd
, tabs
, basename
, "")) return 1;
283 fprintf(fd
, " *array;\n");
289 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
290 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
291 type_descriptor_t
*type
= field
->type
;
292 if(type
->type_name
== NULL
) {
293 /* Not a named nested type : we must print its declaration first */
294 if(print_type_declaration(type
,
295 fd
, 0, basename
, field
->name
)) return 1;
298 fprintf(fd
, "struct lttng_%s", basename
);
300 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
301 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
302 type_descriptor_t
*type
= field
->type
;
304 if(print_type(type
, fd
, tabs
, basename
, field
->name
)) return 1;
306 fprintf(fd
, "%s", field
->name
);
313 /* TODO : Do not allow variable length fields in a union */
314 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
315 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
316 type_descriptor_t
*type
= field
->type
;
317 if(type
->type_name
== NULL
) {
318 /* Not a named nested type : we must print its declaration first */
319 if(print_type_declaration(type
,
320 fd
, 0, basename
, field
->name
)) return 1;
323 fprintf(fd
, "union lttng_%s", basename
);
325 for(unsigned i
=0;i
<td
->fields
.position
;i
++){
326 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
327 type_descriptor_t
*type
= field
->type
;
329 if(print_type(type
, fd
, tabs
, basename
, field
->name
)) return 1;
331 fprintf(fd
, "%s", field
->name
);
338 dprintf("print_type_declaration : unknown type or nothing to declare.\n");
345 /* Print the logging function of an event. This is the core of genevent */
346 int print_event_logging_function(char *basename
, event_t
*event
, FILE *fd
)
348 fprintf(fd
, "static inline void trace_%s(\n", basename
);
349 for(unsigned int j
= 0; j
< event
->fields
.position
; j
++) {
350 /* For each field, print the function argument */
351 field_t
*f
= (field_t
*)event
->fields
.array
[j
];
352 type_descriptor_t
*t
= f
->type
;
354 if(print_type(t
, fd
, 0, basename
, f
->name
)) return 1;
355 fprintf(fd
, " %s", f
->name
);
356 if(j
< event
->fields
.position
-1) {
361 if(event
->fields
.position
== 0) {
366 fprintf(fd
, "#ifndef CONFIG_LTT\n");
369 fprintf(fd
,"#else\n");
374 fprintf(fd
, "#endif //CONFIG_LTT\n\n");
379 /* ltt-facility-name.h : main logging header.
382 void print_log_header_head(facility_t
*fac
, FILE *fd
)
384 fprintf(fd
, "#ifndef _LTT_FACILITY_%s_H_\n", fac
->capname
);
385 fprintf(fd
, "#define _LTT_FACILITY_%s_H_\n\n", fac
->capname
);
387 fprintf(fd
, "/* Facility activation at compile time. */\n");
388 fprintf(fd
, "#ifdef CONFIG_LTT_FACILITY_%s\n\n", fac
->capname
);
393 int print_log_header_types(facility_t
*fac
, FILE *fd
)
395 sequence_t
*types
= &fac
->named_types
.values
;
396 fprintf(fd
, "/* Named types */\n");
399 for(unsigned int i
= 0; i
< types
->position
; i
++) {
400 /* For each named type, print the definition */
401 if((print_type_declaration(types
->array
[i
], fd
,
402 0, "", ""))) return 1;
407 int print_log_header_events(facility_t
*fac
, FILE *fd
)
409 sequence_t
*events
= &fac
->events
;
410 char basename
[PATH_MAX
];
411 unsigned int facname_len
;
413 strncpy(basename
, fac
->name
, PATH_MAX
);
414 facname_len
= strlen(basename
);
415 strncat(basename
, "_", PATH_MAX
-facname_len
);
416 facname_len
= strlen(basename
);
418 for(unsigned int i
= 0; i
< events
->position
; i
++) {
419 event_t
*event
= (event_t
*)events
->array
[i
];
420 strncpy(&basename
[facname_len
], event
->name
, PATH_MAX
-facname_len
);
422 /* For each event, print structure, and then logging function */
423 fprintf(fd
, "/* Event %s structures */\n",
425 for(unsigned int j
= 0; j
< event
->fields
.position
; j
++) {
426 /* For each unnamed type, print the definition */
427 field_t
*f
= (field_t
*)event
->fields
.array
[j
];
428 type_descriptor_t
*t
= f
->type
;
429 if(t
->type_name
== NULL
)
430 if((print_type_declaration(t
, fd
, 0, basename
, f
->name
))) return 1;
434 fprintf(fd
, "/* Event %s logging function */\n",
437 if(print_event_logging_function(basename
, event
, fd
)) return 1;
446 void print_log_header_tail(facility_t
*fac
, FILE *fd
)
448 fprintf(fd
, "#endif //CONFIG_LTT_FACILITY_%s\n\n", fac
->capname
);
449 fprintf(fd
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
452 int print_log_header(facility_t
*fac
)
454 char filename
[PATH_MAX
];
455 unsigned int filename_size
= 0;
457 dprintf("%s\n", fac
->name
);
459 strcpy(filename
, "ltt-facility-");
460 filename_size
= strlen(filename
);
462 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
463 filename_size
= strlen(filename
);
465 strncat(filename
, ".h", PATH_MAX
- filename_size
);
466 filename_size
= strlen(filename
);
469 fd
= fopen(filename
, "w");
471 printf("Error opening file %s for writing : %s\n",
472 filename
, strerror(errno
));
476 /* Print file head */
477 print_log_header_head(fac
, fd
);
479 /* print named types in declaration order */
480 if(print_log_header_types(fac
, fd
)) return 1;
483 if(print_log_header_events(fac
, fd
)) return 1;
485 /* Print file tail */
486 print_log_header_tail(fac
, fd
);
495 /* ltt-facility-id-name.h : facility id.
497 int print_id_header(facility_t
*fac
)
499 char filename
[PATH_MAX
];
500 unsigned int filename_size
= 0;
502 dprintf("%s\n", fac
->name
);
504 strcpy(filename
, "ltt-facility-id-");
505 filename_size
= strlen(filename
);
507 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
508 filename_size
= strlen(filename
);
510 strncat(filename
, ".h", PATH_MAX
- filename_size
);
511 filename_size
= strlen(filename
);
514 fd
= fopen(filename
, "w");
516 printf("Error opening file %s for writing : %s\n",
517 filename
, strerror(errno
));
527 /* ltt-facility-loader-name.h : facility specific loader info.
529 int print_loader_header(facility_t
*fac
)
531 char filename
[PATH_MAX
];
532 unsigned int filename_size
= 0;
534 dprintf("%s\n", fac
->name
);
536 strcpy(filename
, "ltt-facility-loader-");
537 filename_size
= strlen(filename
);
539 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
540 filename_size
= strlen(filename
);
542 strncat(filename
, ".h", PATH_MAX
- filename_size
);
543 filename_size
= strlen(filename
);
546 fd
= fopen(filename
, "w");
548 printf("Error opening file %s for writing : %s\n",
549 filename
, strerror(errno
));
558 /* ltt-facility-loader-name.c : generic faciilty loader
560 int print_loader_c(facility_t
*fac
)
562 char filename
[PATH_MAX
];
563 unsigned int filename_size
= 0;
565 dprintf("%s\n", fac
->name
);
567 strcpy(filename
, "ltt-facility-loader-");
568 filename_size
= strlen(filename
);
570 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
571 filename_size
= strlen(filename
);
573 strncat(filename
, ".c", PATH_MAX
- filename_size
);
574 filename_size
= strlen(filename
);
577 fd
= fopen(filename
, "w");
579 printf("Error opening file %s for writing : %s\n",
580 filename
, strerror(errno
));
593 /* code taken from ltt_facility_open in ltt/facility.c in lttv */
595 /*****************************************************************************
597 * ltt_facility_open : open facilities
599 * pathname : the path name of the facility
601 * Open the facility corresponding to the right checksum.
603 *returns the facility on success, NULL on error.
604 ****************************************************************************/
605 facility_t
*ltt_facility_open(char * pathname
)
610 facility_t
* fac
= NULL
;
611 unsigned long checksum
;
612 char buffer
[BUFFER_SIZE
];
613 int generated
= FALSE
;
615 in
.buffer
= &(buffer
[0]);
617 in
.error
= error_callback
;
621 in
.fp
= fopen(in
.name
, "r");
628 token
= getToken(&in
);
629 if(in
.type
== ENDFILE
) break;
632 printf("More than one facility in the file. Only using the first one.\n");
636 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
637 token
= getName(&in
);
639 if(strcmp("facility",token
) == 0) {
640 fac
= malloc(sizeof(facility_t
));
642 fac
->description
= NULL
;
643 sequence_init(&(fac
->events
));
644 table_init(&(fac
->named_types
));
645 sequence_init(&(fac
->unnamed_types
));
647 parseFacility(&in
, fac
);
649 //check if any namedType is not defined
650 checkNamedTypesImplemented(&fac
->named_types
);
652 generateChecksum(fac
->name
, &checksum
, &fac
->events
);
657 printf("facility token was expected in file %s\n", in
.name
);
668 printf("Cannot find facility %s\n", pathname
);
675 /* Close the facility */
676 void ltt_facility_close(facility_t
*fac
)
680 free(fac
->description
);
681 freeEvents(&fac
->events
);
682 sequence_dispose(&fac
->events
);
683 freeNamedType(&fac
->named_types
);
684 table_dispose(&fac
->named_types
);
685 freeTypes(&fac
->unnamed_types
);
686 sequence_dispose(&fac
->unnamed_types
);
692 void show_help(int argc
, char ** argv
)
694 printf("Genevent help : \n");
696 printf("Use %s name.xml\n", argv
[0]);
697 printf("to create :\n");
698 printf("ltt-facility-name.h\n");
699 printf("ltt-facility-id-name.h\n");
700 printf("ltt-facility-loader-name.h\n");
701 printf("ltt-facility-loader-name.c\n");
702 printf("In the current directory.\n");
706 /* Parse program arguments */
708 * 0 : continue program
709 * -1 : stop program, return 0
710 * > 0 : stop program, return value as exit.
712 int check_args(int argc
, char **argv
)
715 printf("Not enough arguments\n");
716 show_help(argc
, argv
);
720 if(strcmp(argv
[1], "-h") == 0) {
721 show_help(argc
, argv
);
728 int main(int argc
, char **argv
)
733 err
= check_args(argc
, argv
);
734 if(err
> 0) return err
;
735 else if(err
< 0) return 0;
737 /* open the facility */
738 fac
= ltt_facility_open(argv
[1]);
740 printf("Error opening file %s for reading : %s\n",
741 argv
[1], strerror(errno
));
745 /* generate the output C files */
748 /* ltt-facility-name.h : main logging header.
750 err
= print_log_header(fac
);
753 /* ltt-facility-id-name.h : facility id.
755 err
= print_id_header(fac
);
758 /* ltt-facility-loader-name.h : facility specific loader info.
760 err
= print_loader_header(fac
);
763 /* ltt-facility-loader-name.c : generic faciilty loader
765 err
= print_loader_c(fac
);
768 /* close the facility */
769 ltt_facility_close(fac
);
This page took 0.069072 seconds and 4 git commands to generate.