c1b1363e6d2ba83d8cc384dc7b6f4082df341a64
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
);
105 * Copied from construct_types_and_fields in LTTV facility.c */
107 int print_type(type_descriptor_t
* td
, FILE *fd
, unsigned int tabs
,
108 char *nest_name
, char *field_name
)
110 char basename
[PATH_MAX
];
111 unsigned int basename_len
= 0;
113 strcpy(basename
, nest_name
);
114 basename_len
= strlen(basename
);
116 /* For a named type, we use the type_name directly */
117 if(td
->type_name
!= NULL
) {
118 strncpy(basename
, td
->type_name
, PATH_MAX
);
119 basename_len
= strlen(basename
);
121 /* For a unnamed type, there must be a field name */
122 if((basename_len
!= 0)
123 && (basename
[basename_len
-1] != '_')
124 && (field_name
[0] != '\0')) {
125 strncat(basename
, "_", PATH_MAX
- basename_len
);
126 basename_len
= strlen(basename
);
128 strncat(basename
, field_name
, PATH_MAX
- basename_len
);
133 fprintf(fd
, "%s", intOutputTypes
[getSizeindex(td
->size
)]);
136 fprintf(fd
, "%s", uintOutputTypes
[getSizeindex(td
->size
)]);
139 fprintf(fd
, "signed char");
142 fprintf(fd
, "unsigned char");
145 fprintf(fd
, "short");
148 fprintf(fd
, "unsigned short");
154 fprintf(fd
, "unsigned int");
157 fprintf(fd
, "%s", floatOutputTypes
[getSizeindex(td
->size
)]);
160 fprintf(fd
, "void *");
166 fprintf(fd
, "unsigned long");
169 fprintf(fd
, "size_t");
172 fprintf(fd
, "ssize_t");
175 fprintf(fd
, "off_t");
178 fprintf(fd
, "char *");
181 fprintf(fd
, "enum lttng_%s", basename
);
184 fprintf(fd
, "lttng_array_%s", basename
);
187 fprintf(fd
, "lttng_sequence_%s", basename
);
190 fprintf(fd
, "struct lttng_%s", basename
);
193 fprintf(fd
, "union lttng_%s", basename
);
196 printf("print_type : unknown type\n");
203 /* Print logging function argument */
204 int print_arg(type_descriptor_t
* td
, FILE *fd
, unsigned int tabs
,
205 char *nest_name
, char *field_name
)
207 char basename
[PATH_MAX
];
208 unsigned int basename_len
= 0;
210 strcpy(basename
, nest_name
);
211 basename_len
= strlen(basename
);
213 /* For a named type, we use the type_name directly */
214 if(td
->type_name
!= NULL
) {
215 strncpy(basename
, td
->type_name
, PATH_MAX
);
216 basename_len
= strlen(basename
);
218 /* For a unnamed type, there must be a field name */
219 if((basename_len
!= 0)
220 && (basename
[basename_len
-1] != '_')
221 && (field_name
[0] != '\0')) {
222 strncat(basename
, "_", PATH_MAX
- basename_len
);
223 basename_len
= strlen(basename
);
225 strncat(basename
, field_name
, PATH_MAX
- basename_len
);
228 print_tabs(tabs
, fd
);
232 fprintf(fd
, "%s", intOutputTypes
[getSizeindex(td
->size
)]);
233 fprintf(fd
, " %s", field_name
);
236 fprintf(fd
, "%s", uintOutputTypes
[getSizeindex(td
->size
)]);
237 fprintf(fd
, " %s", field_name
);
240 fprintf(fd
, "signed char");
241 fprintf(fd
, " %s", field_name
);
244 fprintf(fd
, "unsigned char");
245 fprintf(fd
, " %s", field_name
);
248 fprintf(fd
, "short");
249 fprintf(fd
, " %s", field_name
);
252 fprintf(fd
, "unsigned short");
253 fprintf(fd
, " %s", field_name
);
257 fprintf(fd
, " %s", field_name
);
260 fprintf(fd
, "unsigned int");
261 fprintf(fd
, " %s", field_name
);
264 fprintf(fd
, "%s", floatOutputTypes
[getSizeindex(td
->size
)]);
265 fprintf(fd
, " %s", field_name
);
268 fprintf(fd
, "void *");
269 fprintf(fd
, " %s", field_name
);
273 fprintf(fd
, " %s", field_name
);
276 fprintf(fd
, "unsigned long");
277 fprintf(fd
, " %s", field_name
);
280 fprintf(fd
, "size_t");
281 fprintf(fd
, " %s", field_name
);
284 fprintf(fd
, "ssize_t");
285 fprintf(fd
, " %s", field_name
);
288 fprintf(fd
, "off_t");
289 fprintf(fd
, " %s", field_name
);
292 fprintf(fd
, "char *");
293 fprintf(fd
, " %s", field_name
);
296 fprintf(fd
, "enum lttng_%s", basename
);
297 fprintf(fd
, " %s", field_name
);
300 fprintf(fd
, "lttng_array_%s", basename
);
301 fprintf(fd
, " %s", field_name
);
304 fprintf(fd
, "lttng_sequence_%s *", basename
);
305 fprintf(fd
, " %s", field_name
);
308 fprintf(fd
, "struct lttng_%s *", basename
);
309 fprintf(fd
, " %s", field_name
);
312 fprintf(fd
, "union lttng_%s *", basename
);
313 fprintf(fd
, " %s", field_name
);
316 printf("print_type : unknown type\n");
324 /* print type declaration.
326 * Copied from construct_types_and_fields in LTTV facility.c */
328 int print_type_declaration(type_descriptor_t
* td
, FILE *fd
, unsigned int tabs
,
329 char *nest_name
, char *field_name
)
331 char basename
[PATH_MAX
];
332 unsigned int basename_len
= 0;
334 strncpy(basename
, nest_name
, PATH_MAX
);
335 basename_len
= strlen(basename
);
337 /* For a named type, we use the type_name directly */
338 if(td
->type_name
!= NULL
) {
339 strncpy(basename
, td
->type_name
, PATH_MAX
);
340 basename_len
= strlen(basename
);
342 /* For a unnamed type, there must be a field name, except for
344 if((basename_len
!= 0)
345 && (basename
[basename_len
-1] != '_'
346 && (field_name
[0] != '\0'))) {
347 strncat(basename
, "_", PATH_MAX
- basename_len
);
348 basename_len
= strlen(basename
);
350 strncat(basename
, field_name
, PATH_MAX
- basename_len
);
355 fprintf(fd
, "enum lttng_%s", basename
);
357 for(unsigned int i
=0;i
<td
->labels
.position
;i
++){
359 fprintf(fd
, "LTTNG_%s", ((char*)(td
->labels
.array
[i
])));
367 dprintf("%s\n", basename
);
368 assert(td
->size
>= 0);
369 if(td
->nested_type
->type_name
== NULL
) {
370 /* Not a named nested type : we must print its declaration first */
371 if(print_type_declaration(td
->nested_type
,
372 fd
, 0, basename
, "")) return 1;
374 fprintf(fd
, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename
,
376 fprintf(fd
, "typedef ");
377 if(print_type(td
->nested_type
, fd
, tabs
, basename
, "")) return 1;
378 fprintf(fd
, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename
,
383 if(td
->nested_type
->type_name
== NULL
) {
384 /* Not a named nested type : we must print its declaration first */
385 if(print_type_declaration(td
->nested_type
,
386 fd
, 0, basename
, "")) return 1;
388 fprintf(fd
, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n",
391 fprintf(fd
, "struct lttng_sequence_%s", basename
);
394 fprintf(fd
, "unsigned int len;\n");
396 if(print_type(td
->nested_type
, fd
, tabs
, basename
, "")) return 1;
397 fprintf(fd
, " *array;\n");
403 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
404 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
405 type_descriptor_t
*type
= field
->type
;
406 if(type
->type_name
== NULL
) {
407 /* Not a named nested type : we must print its declaration first */
408 if(print_type_declaration(type
,
409 fd
, 0, basename
, field
->name
)) return 1;
412 fprintf(fd
, "struct lttng_%s", basename
);
414 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
415 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
416 type_descriptor_t
*type
= field
->type
;
418 if(print_type(type
, fd
, tabs
, basename
, field
->name
)) return 1;
420 fprintf(fd
, "%s", field
->name
);
427 /* TODO : Do not allow variable length fields in a union */
428 for(unsigned int i
=0;i
<td
->fields
.position
;i
++){
429 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
430 type_descriptor_t
*type
= field
->type
;
431 if(type
->type_name
== NULL
) {
432 /* Not a named nested type : we must print its declaration first */
433 if(print_type_declaration(type
,
434 fd
, 0, basename
, field
->name
)) return 1;
437 fprintf(fd
, "union lttng_%s", basename
);
439 for(unsigned i
=0;i
<td
->fields
.position
;i
++){
440 field_t
*field
= (field_t
*)(td
->fields
.array
[i
]);
441 type_descriptor_t
*type
= field
->type
;
443 if(print_type(type
, fd
, tabs
, basename
, field
->name
)) return 1;
445 fprintf(fd
, "%s", field
->name
);
452 dprintf("print_type_declaration : unknown type or nothing to declare.\n");
459 /* Print the logging function of an event. This is the core of genevent */
460 int print_event_logging_function(char *basename
, event_t
*event
, FILE *fd
)
462 fprintf(fd
, "static inline void trace_%s(\n", basename
);
463 for(unsigned int j
= 0; j
< event
->fields
.position
; j
++) {
464 /* For each field, print the function argument */
465 field_t
*f
= (field_t
*)event
->fields
.array
[j
];
466 type_descriptor_t
*t
= f
->type
;
467 if(print_arg(t
, fd
, 2, basename
, f
->name
)) return 1;
468 if(j
< event
->fields
.position
-1) {
473 if(event
->fields
.position
== 0) {
478 fprintf(fd
, "#ifndef CONFIG_LTT\n");
481 fprintf(fd
,"#else\n");
483 /* Print the function variables */
485 /* Calculate event variable len + event alignment offset.
486 * Assume that the padding for alignment starts at a void*
489 /* Take locks : make sure the trace does not vanish while we write on
490 * it. A simple preemption disabling is enough (using rcu traces). */
495 /* If error, increment counter and return */
504 fprintf(fd
, "#endif //CONFIG_LTT\n\n");
509 /* ltt-facility-name.h : main logging header.
512 void print_log_header_head(facility_t
*fac
, FILE *fd
)
514 fprintf(fd
, "#ifndef _LTT_FACILITY_%s_H_\n", fac
->capname
);
515 fprintf(fd
, "#define _LTT_FACILITY_%s_H_\n\n", fac
->capname
);
517 fprintf(fd
, "/* Facility activation at compile time. */\n");
518 fprintf(fd
, "#ifdef CONFIG_LTT_FACILITY_%s\n\n", fac
->capname
);
523 int print_log_header_types(facility_t
*fac
, FILE *fd
)
525 sequence_t
*types
= &fac
->named_types
.values
;
526 fprintf(fd
, "/* Named types */\n");
529 for(unsigned int i
= 0; i
< types
->position
; i
++) {
530 /* For each named type, print the definition */
531 if((print_type_declaration(types
->array
[i
], fd
,
532 0, "", ""))) return 1;
537 int print_log_header_events(facility_t
*fac
, FILE *fd
)
539 sequence_t
*events
= &fac
->events
;
540 char basename
[PATH_MAX
];
541 unsigned int facname_len
;
543 strncpy(basename
, fac
->name
, PATH_MAX
);
544 facname_len
= strlen(basename
);
545 strncat(basename
, "_", PATH_MAX
-facname_len
);
546 facname_len
= strlen(basename
);
548 for(unsigned int i
= 0; i
< events
->position
; i
++) {
549 event_t
*event
= (event_t
*)events
->array
[i
];
550 strncpy(&basename
[facname_len
], event
->name
, PATH_MAX
-facname_len
);
552 /* For each event, print structure, and then logging function */
553 fprintf(fd
, "/* Event %s structures */\n",
555 for(unsigned int j
= 0; j
< event
->fields
.position
; j
++) {
556 /* For each unnamed type, print the definition */
557 field_t
*f
= (field_t
*)event
->fields
.array
[j
];
558 type_descriptor_t
*t
= f
->type
;
559 if(t
->type_name
== NULL
)
560 if((print_type_declaration(t
, fd
, 0, basename
, f
->name
))) return 1;
564 fprintf(fd
, "/* Event %s logging function */\n",
567 if(print_event_logging_function(basename
, event
, fd
)) return 1;
576 void print_log_header_tail(facility_t
*fac
, FILE *fd
)
578 fprintf(fd
, "#endif //CONFIG_LTT_FACILITY_%s\n\n", fac
->capname
);
579 fprintf(fd
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
582 int print_log_header(facility_t
*fac
)
584 char filename
[PATH_MAX
];
585 unsigned int filename_size
= 0;
587 dprintf("%s\n", fac
->name
);
589 strcpy(filename
, "ltt-facility-");
590 filename_size
= strlen(filename
);
592 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
593 filename_size
= strlen(filename
);
595 strncat(filename
, ".h", PATH_MAX
- filename_size
);
596 filename_size
= strlen(filename
);
599 fd
= fopen(filename
, "w");
601 printf("Error opening file %s for writing : %s\n",
602 filename
, strerror(errno
));
606 /* Print file head */
607 print_log_header_head(fac
, fd
);
609 /* print named types in declaration order */
610 if(print_log_header_types(fac
, fd
)) return 1;
613 if(print_log_header_events(fac
, fd
)) return 1;
615 /* Print file tail */
616 print_log_header_tail(fac
, fd
);
625 /* ltt-facility-id-name.h : facility id.
627 int print_id_header(facility_t
*fac
)
629 char filename
[PATH_MAX
];
630 unsigned int filename_size
= 0;
632 dprintf("%s\n", fac
->name
);
634 strcpy(filename
, "ltt-facility-id-");
635 filename_size
= strlen(filename
);
637 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
638 filename_size
= strlen(filename
);
640 strncat(filename
, ".h", PATH_MAX
- filename_size
);
641 filename_size
= strlen(filename
);
644 fd
= fopen(filename
, "w");
646 printf("Error opening file %s for writing : %s\n",
647 filename
, strerror(errno
));
657 /* ltt-facility-loader-name.h : facility specific loader info.
659 int print_loader_header(facility_t
*fac
)
661 char filename
[PATH_MAX
];
662 unsigned int filename_size
= 0;
664 dprintf("%s\n", fac
->name
);
666 strcpy(filename
, "ltt-facility-loader-");
667 filename_size
= strlen(filename
);
669 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
670 filename_size
= strlen(filename
);
672 strncat(filename
, ".h", PATH_MAX
- filename_size
);
673 filename_size
= strlen(filename
);
676 fd
= fopen(filename
, "w");
678 printf("Error opening file %s for writing : %s\n",
679 filename
, strerror(errno
));
688 /* ltt-facility-loader-name.c : generic faciilty loader
690 int print_loader_c(facility_t
*fac
)
692 char filename
[PATH_MAX
];
693 unsigned int filename_size
= 0;
695 dprintf("%s\n", fac
->name
);
697 strcpy(filename
, "ltt-facility-loader-");
698 filename_size
= strlen(filename
);
700 strncat(filename
, fac
->name
, PATH_MAX
- filename_size
);
701 filename_size
= strlen(filename
);
703 strncat(filename
, ".c", PATH_MAX
- filename_size
);
704 filename_size
= strlen(filename
);
707 fd
= fopen(filename
, "w");
709 printf("Error opening file %s for writing : %s\n",
710 filename
, strerror(errno
));
723 /* code taken from ltt_facility_open in ltt/facility.c in lttv */
725 /*****************************************************************************
727 * ltt_facility_open : open facilities
729 * pathname : the path name of the facility
731 * Open the facility corresponding to the right checksum.
733 *returns the facility on success, NULL on error.
734 ****************************************************************************/
735 facility_t
*ltt_facility_open(char * pathname
)
740 facility_t
* fac
= NULL
;
741 unsigned long checksum
;
742 char buffer
[BUFFER_SIZE
];
743 int generated
= FALSE
;
745 in
.buffer
= &(buffer
[0]);
747 in
.error
= error_callback
;
751 in
.fp
= fopen(in
.name
, "r");
758 token
= getToken(&in
);
759 if(in
.type
== ENDFILE
) break;
762 printf("More than one facility in the file. Only using the first one.\n");
766 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
767 token
= getName(&in
);
769 if(strcmp("facility",token
) == 0) {
770 fac
= malloc(sizeof(facility_t
));
772 fac
->description
= NULL
;
773 sequence_init(&(fac
->events
));
774 table_init(&(fac
->named_types
));
775 sequence_init(&(fac
->unnamed_types
));
777 parseFacility(&in
, fac
);
779 //check if any namedType is not defined
780 checkNamedTypesImplemented(&fac
->named_types
);
782 generateChecksum(fac
->name
, &checksum
, &fac
->events
);
787 printf("facility token was expected in file %s\n", in
.name
);
798 printf("Cannot find facility %s\n", pathname
);
805 /* Close the facility */
806 void ltt_facility_close(facility_t
*fac
)
810 free(fac
->description
);
811 freeEvents(&fac
->events
);
812 sequence_dispose(&fac
->events
);
813 freeNamedType(&fac
->named_types
);
814 table_dispose(&fac
->named_types
);
815 freeTypes(&fac
->unnamed_types
);
816 sequence_dispose(&fac
->unnamed_types
);
822 void show_help(int argc
, char ** argv
)
824 printf("Genevent help : \n");
826 printf("Use %s name.xml\n", argv
[0]);
827 printf("to create :\n");
828 printf("ltt-facility-name.h\n");
829 printf("ltt-facility-id-name.h\n");
830 printf("ltt-facility-loader-name.h\n");
831 printf("ltt-facility-loader-name.c\n");
832 printf("In the current directory.\n");
836 /* Parse program arguments */
838 * 0 : continue program
839 * -1 : stop program, return 0
840 * > 0 : stop program, return value as exit.
842 int check_args(int argc
, char **argv
)
845 printf("Not enough arguments\n");
846 show_help(argc
, argv
);
850 if(strcmp(argv
[1], "-h") == 0) {
851 show_help(argc
, argv
);
858 int main(int argc
, char **argv
)
863 err
= check_args(argc
, argv
);
864 if(err
> 0) return err
;
865 else if(err
< 0) return 0;
867 /* open the facility */
868 fac
= ltt_facility_open(argv
[1]);
870 printf("Error opening file %s for reading : %s\n",
871 argv
[1], strerror(errno
));
875 /* generate the output C files */
878 /* ltt-facility-name.h : main logging header.
880 err
= print_log_header(fac
);
883 /* ltt-facility-id-name.h : facility id.
885 err
= print_id_header(fac
);
888 /* ltt-facility-loader-name.h : facility specific loader info.
890 err
= print_loader_header(fac
);
893 /* ltt-facility-loader-name.c : generic faciilty loader
895 err
= print_loader_c(fac
);
898 /* close the facility */
899 ltt_facility_close(fac
);
This page took 0.084526 seconds and 4 git commands to generate.