update usertrade to support g++
[lttv.git] / genevent / genevent.c
CommitLineData
92d82357 1/******************************************************************************
2 * Genevent
3 *
4 * Event generator. XML to logging C code converter.
5 *
6 * Program parameters :
7 * ./genevent name.xml
8 *
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.
12 *
13 * Supports :
14 * - C Alignment
15 * - C types : struct, union, enum, basic types.
16 * - Architectures : LP32, ILP32, ILP64, LLP64, LP64.
17 *
18 * Additionnal structures supported :
19 * - embedded variable size strings
20 * - embedded variable size arrays
21 * - embedded variable size sequences
22 *
23 * Notes :
24 * (1)
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.
29 *
30 * (2)
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.
34 *
35 * Note that, from
36 * http://www.usenix.org/publications/login/standards/10.data.html
37 * (Andrew Josey <a.josey@opengroup.org>) :
38 *
39 * Data Type LP32 ILP32 ILP64 LLP64 LP64
40 * char 8 8 8 8 8
41 * short 16 16 16 16 16
42 * int32 32
43 * int 16 32 64 32 32
44 * long 32 32 64 32 64
45 * long long (int64) 64
46 * pointer 32 32 64 64 64
47 *
48 * With these constraints :
49 * sizeof(char) <= sizeof(short) <= sizeof(int)
50 * <= sizeof(long) = sizeof(size_t)
51 *
52 * and therefore sizeof(long) <= sizeof(pointer) <= sizeof(size_t)
53 *
54 * Which means we only have to remember which is the biggest type in a structure
55 * to know the structure's alignment.
56 */
57
2d2d14a7 58#define _GNU_SOURCE
59#include <limits.h>
60#include <stdlib.h>
92d82357 61#include <errno.h>
62#include <sys/types.h>
63#include <sys/stat.h>
64#include <fcntl.h>
65#include <stdio.h>
66#include <string.h>
67#include <unistd.h>
2d2d14a7 68#include <assert.h>
92d82357 69
70#include "genevent.h"
71#include "parser.h"
72
73
74#define TRUE 1
75#define FALSE (!TRUE)
76
2d2d14a7 77/* Debugging printf */
78#ifdef DEBUG
79#define dprintf(...) \
80 do {\
81 printf(__FILE__ ",%u,%s: ",\
82 __LINE__, __func__);\
83 printf(__VA_ARGS__);\
84 } while(0)
85#else
86#define dprintf(...)
87#endif
88
92d82357 89/* Code printing */
90
2d2d14a7 91void print_tabs(unsigned int tabs, FILE *fd)
92{
93 for(unsigned int i = 0; i<tabs;i++)
94 fprintf(fd, "\t");
95}
96
2d2d14a7 97/* print type.
98 *
99 * Copied from construct_types_and_fields in LTTV facility.c */
100
101int print_type(type_descriptor_t * td, FILE *fd, unsigned int tabs,
102 char *nest_name, char *field_name)
103{
104 char basename[PATH_MAX];
105 unsigned int basename_len = 0;
106
107 strcpy(basename, nest_name);
108 basename_len = strlen(basename);
109
110 /* For a named type, we use the type_name directly */
111 if(td->type_name != NULL) {
112 strncpy(basename, td->type_name, PATH_MAX);
113 basename_len = strlen(basename);
114 } else {
115 /* For a unnamed type, there must be a field name */
7b175edc 116 if((basename_len != 0)
117 && (basename[basename_len-1] != '_')
118 && (field_name[0] != '\0')) {
2d2d14a7 119 strncat(basename, "_", PATH_MAX - basename_len);
120 basename_len = strlen(basename);
121 }
122 strncat(basename, field_name, PATH_MAX - basename_len);
123 }
124
125 switch(td->type) {
126 case INT_FIXED:
127 fprintf(fd, "%s", intOutputTypes[getSizeindex(td->size)]);
128 break;
129 case UINT_FIXED:
130 fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]);
131 break;
132 case CHAR:
133 fprintf(fd, "signed char");
134 break;
135 case UCHAR:
136 fprintf(fd, "unsigned char");
137 break;
138 case SHORT:
139 fprintf(fd, "short");
140 break;
141 case USHORT:
142 fprintf(fd, "unsigned short");
143 break;
144 case INT:
145 fprintf(fd, "int");
146 break;
147 case UINT:
148 fprintf(fd, "unsigned int");
149 break;
150 case FLOAT:
151 fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]);
152 break;
153 case POINTER:
458989d8 154 fprintf(fd, "const void *");
2d2d14a7 155 break;
156 case LONG:
157 fprintf(fd, "long");
158 break;
159 case ULONG:
160 fprintf(fd, "unsigned long");
161 break;
162 case SIZE_T:
163 fprintf(fd, "size_t");
164 break;
165 case SSIZE_T:
166 fprintf(fd, "ssize_t");
167 break;
168 case OFF_T:
169 fprintf(fd, "off_t");
170 break;
171 case STRING:
3d9b9b0c 172 fprintf(fd, "const char *");
2d2d14a7 173 break;
174 case ENUM:
175 fprintf(fd, "enum lttng_%s", basename);
176 break;
177 case ARRAY:
178 fprintf(fd, "lttng_array_%s", basename);
179 break;
180 case SEQUENCE:
181 fprintf(fd, "lttng_sequence_%s", basename);
182 break;
183 case STRUCT:
184 fprintf(fd, "struct lttng_%s", basename);
185 break;
186 case UNION:
187 fprintf(fd, "union lttng_%s", basename);
188 break;
189 default:
190 printf("print_type : unknown type\n");
191 return 1;
192 }
193
194 return 0;
195}
196
7e97b039 197/* Print logging function argument */
198int print_arg(type_descriptor_t * td, FILE *fd, unsigned int tabs,
199 char *nest_name, char *field_name)
200{
201 char basename[PATH_MAX];
202 unsigned int basename_len = 0;
203
204 strcpy(basename, nest_name);
205 basename_len = strlen(basename);
206
207 /* For a named type, we use the type_name directly */
208 if(td->type_name != NULL) {
209 strncpy(basename, td->type_name, PATH_MAX);
210 basename_len = strlen(basename);
211 } else {
212 /* For a unnamed type, there must be a field name */
213 if((basename_len != 0)
214 && (basename[basename_len-1] != '_')
215 && (field_name[0] != '\0')) {
216 strncat(basename, "_", PATH_MAX - basename_len);
217 basename_len = strlen(basename);
218 }
219 strncat(basename, field_name, PATH_MAX - basename_len);
220 }
221
222 print_tabs(tabs, fd);
223
224 switch(td->type) {
225 case INT_FIXED:
226 fprintf(fd, "%s", intOutputTypes[getSizeindex(td->size)]);
1f42154b 227 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 228 break;
229 case UINT_FIXED:
230 fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]);
1f42154b 231 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 232 break;
233 case CHAR:
234 fprintf(fd, "signed char");
3ace7bc4 235 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 236 break;
237 case UCHAR:
238 fprintf(fd, "unsigned char");
3ace7bc4 239 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 240 break;
241 case SHORT:
242 fprintf(fd, "short");
3ace7bc4 243 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 244 break;
245 case USHORT:
246 fprintf(fd, "unsigned short");
3ace7bc4 247 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 248 break;
249 case INT:
250 fprintf(fd, "int");
3ace7bc4 251 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 252 break;
253 case UINT:
254 fprintf(fd, "unsigned int");
3ace7bc4 255 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 256 break;
257 case FLOAT:
258 fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]);
3ace7bc4 259 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 260 break;
261 case POINTER:
458989d8 262 fprintf(fd, "const void *");
3ace7bc4 263 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 264 break;
265 case LONG:
266 fprintf(fd, "long");
3ace7bc4 267 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 268 break;
269 case ULONG:
270 fprintf(fd, "unsigned long");
3ace7bc4 271 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 272 break;
273 case SIZE_T:
274 fprintf(fd, "size_t");
3ace7bc4 275 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 276 break;
277 case SSIZE_T:
278 fprintf(fd, "ssize_t");
3ace7bc4 279 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 280 break;
281 case OFF_T:
282 fprintf(fd, "off_t");
3ace7bc4 283 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 284 break;
285 case STRING:
3d9b9b0c 286 fprintf(fd, "const char *");
3ace7bc4 287 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 288 break;
289 case ENUM:
290 fprintf(fd, "enum lttng_%s", basename);
3ace7bc4 291 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 292 break;
293 case ARRAY:
294 fprintf(fd, "lttng_array_%s", basename);
3ace7bc4 295 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 296 break;
297 case SEQUENCE:
298 fprintf(fd, "lttng_sequence_%s *", basename);
3ace7bc4 299 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 300 break;
301 case STRUCT:
302 fprintf(fd, "struct lttng_%s *", basename);
3ace7bc4 303 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 304 break;
305 case UNION:
306 fprintf(fd, "union lttng_%s *", basename);
3ace7bc4 307 fprintf(fd, " lttng_param_%s", field_name);
7e97b039 308 break;
309 default:
310 printf("print_type : unknown type\n");
311 return 1;
312 }
313
314 return 0;
315}
316
317
a3e6ce64 318/* Does the type has a fixed size ? (as know from the compiler)
319 *
320 * 1 : fixed size
321 * 0 : variable length
322 */
323int has_type_fixed_size(type_descriptor_t *td)
324{
325 switch(td->type) {
326 case INT_FIXED:
327 case UINT_FIXED:
328 case CHAR:
329 case UCHAR:
330 case SHORT:
331 case USHORT:
332 case INT:
333 case UINT:
334 case FLOAT:
335 case POINTER:
336 case LONG:
337 case ULONG:
338 case SIZE_T:
339 case SSIZE_T:
340 case OFF_T:
341 case ENUM:
342 case UNION: /* The union must have fixed size children. Must be checked by
343 the parser */
344 return 1;
345 break;
346 case STRING:
347 case SEQUENCE:
348 return 0;
349 break;
350 case STRUCT:
351 {
352 int has_type_fixed = 0;
353 for(unsigned int i=0;i<td->fields.position;i++){
354 field_t *field = (field_t*)(td->fields.array[i]);
355 type_descriptor_t *type = field->type;
356
357 has_type_fixed = has_type_fixed_size(type);
358 if(!has_type_fixed) return 0;
359 }
360 return 1;
361 }
362 break;
363 case ARRAY:
364 assert(td->size >= 0);
2e415130 365 return has_type_fixed_size(((field_t*)td->fields.array[0])->type);
366 break;
367 case NONE:
368 printf("There is a type defined to NONE : bad.\n");
369 assert(0);
a3e6ce64 370 break;
371 }
2e415130 372 return 0; //make gcc happy.
a3e6ce64 373}
374
375
376
377
378
2d2d14a7 379/* print type declaration.
380 *
381 * Copied from construct_types_and_fields in LTTV facility.c */
382
383int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs,
384 char *nest_name, char *field_name)
385{
386 char basename[PATH_MAX];
387 unsigned int basename_len = 0;
388
64a6ab10 389 if(td->custom_write) return 0; /* Does print custom type */
390
7b175edc 391 strncpy(basename, nest_name, PATH_MAX);
2d2d14a7 392 basename_len = strlen(basename);
393
394 /* For a named type, we use the type_name directly */
395 if(td->type_name != NULL) {
396 strncpy(basename, td->type_name, PATH_MAX);
397 basename_len = strlen(basename);
398 } else {
7b175edc 399 /* For a unnamed type, there must be a field name, except for
400 * the array. */
401 if((basename_len != 0)
402 && (basename[basename_len-1] != '_'
403 && (field_name[0] != '\0'))) {
2d2d14a7 404 strncat(basename, "_", PATH_MAX - basename_len);
405 basename_len = strlen(basename);
406 }
407 strncat(basename, field_name, PATH_MAX - basename_len);
2d2d14a7 408 }
409
410 switch(td->type) {
411 case ENUM:
412 fprintf(fd, "enum lttng_%s", basename);
413 fprintf(fd, " {\n");
414 for(unsigned int i=0;i<td->labels.position;i++){
415 print_tabs(1, fd);
70f46ac3 416 fprintf(fd, "LTTNG_%s = %d", ((char*)td->labels.array[i]),
417 (*(int*)td->labels_values.array[i]));
2d2d14a7 418 fprintf(fd, ",\n");
419 }
420 fprintf(fd, "};\n");
421 fprintf(fd, "\n");
422 break;
423
424 case ARRAY:
7b175edc 425 dprintf("%s\n", basename);
2d2d14a7 426 assert(td->size >= 0);
a67cd958 427 if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
2d2d14a7 428 /* Not a named nested type : we must print its declaration first */
a67cd958 429 if(print_type_declaration(((field_t*)td->fields.array[0])->type,
2d2d14a7 430 fd, 0, basename, "")) return 1;
431 }
2e415130 432 fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %zu\n", basename,
2d2d14a7 433 td->size);
7e97b039 434 fprintf(fd, "typedef ");
a67cd958 435 if(print_type(((field_t*)td->fields.array[0])->type,
436 fd, tabs, basename, "")) return 1;
2d2d14a7 437 fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename,
438 basename);
439 fprintf(fd, "\n");
440 break;
441 case SEQUENCE:
a67cd958 442 /* We assume that the sequence length type does not need to be declared.
443 */
444 if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
2d2d14a7 445 /* Not a named nested type : we must print its declaration first */
a67cd958 446 if(print_type_declaration(((field_t*)td->fields.array[1])->type,
2d2d14a7 447 fd, 0, basename, "")) return 1;
448 }
449 fprintf(fd, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n",
450 basename,
451 basename);
452 fprintf(fd, "struct lttng_sequence_%s", basename);
453 fprintf(fd, " {\n");
454 print_tabs(1, fd);
a3e6ce64 455 if(print_type(((field_t*)td->fields.array[0])->type,
456 fd, tabs, basename, "")) return 1;
40c18b13 457 fprintf(fd, " len;\n");
2d2d14a7 458 print_tabs(1, fd);
8c9e9076 459 fprintf(fd, "const ");
a67cd958 460 if(print_type(((field_t*)td->fields.array[1])->type,
461 fd, tabs, basename, "")) return 1;
2d2d14a7 462 fprintf(fd, " *array;\n");
d428224c 463 fprintf(fd, "};\n"); /* We do not LTT_ALIGN, because we never copy
464 it to the buffer directly. */
2d2d14a7 465 fprintf(fd, "\n");
466 break;
467
468 case STRUCT:
469 for(unsigned int i=0;i<td->fields.position;i++){
470 field_t *field = (field_t*)(td->fields.array[i]);
471 type_descriptor_t *type = field->type;
472 if(type->type_name == NULL) {
473 /* Not a named nested type : we must print its declaration first */
474 if(print_type_declaration(type,
475 fd, 0, basename, field->name)) return 1;
476 }
477 }
478 fprintf(fd, "struct lttng_%s", basename);
479 fprintf(fd, " {\n");
480 for(unsigned int i=0;i<td->fields.position;i++){
481 field_t *field = (field_t*)(td->fields.array[i]);
482 type_descriptor_t *type = field->type;
483 print_tabs(1, fd);
47299663 484 if(print_type(type, fd, tabs, basename, field->name)) return 1;
2d2d14a7 485 fprintf(fd, " ");
486 fprintf(fd, "%s", field->name);
487 fprintf(fd, ";\n");
488 }
d428224c 489 fprintf(fd, "} LTT_ALIGN;\n");
2d2d14a7 490 fprintf(fd, "\n");
491 break;
492 case UNION:
2d2d14a7 493 for(unsigned int i=0;i<td->fields.position;i++){
494 field_t *field = (field_t*)(td->fields.array[i]);
495 type_descriptor_t *type = field->type;
496 if(type->type_name == NULL) {
497 /* Not a named nested type : we must print its declaration first */
47299663 498 if(print_type_declaration(type,
499 fd, 0, basename, field->name)) return 1;
2d2d14a7 500 }
501 }
502 fprintf(fd, "union lttng_%s", basename);
503 fprintf(fd, " {\n");
504 for(unsigned i=0;i<td->fields.position;i++){
505 field_t *field = (field_t*)(td->fields.array[i]);
506 type_descriptor_t *type = field->type;
507 print_tabs(1, fd);
47299663 508 if(print_type(type, fd, tabs, basename, field->name)) return 1;
2d2d14a7 509 fprintf(fd, " ");
510 fprintf(fd, "%s", field->name);
511 fprintf(fd, ";\n");
512 }
d428224c 513 fprintf(fd, "} LTT_ALIGN;\n");
2d2d14a7 514 fprintf(fd, "\n");
515 break;
516 default:
517 dprintf("print_type_declaration : unknown type or nothing to declare.\n");
518 break;
519 }
520
521 return 0;
522}
523
a67cd958 524
a3e6ce64 525/* print type alignment.
526 *
527 * Copied from construct_types_and_fields in LTTV facility.c
528 *
529 * basename is the name which identifies the type (along with a prefix
530 * (possibly)). */
a67cd958 531
a3e6ce64 532int print_type_alignment(type_descriptor_t * td, FILE *fd, unsigned int tabs,
3261899d 533 char *nest_name, char *field_name, char *obj_prefix)
a67cd958 534{
a3e6ce64 535 char basename[PATH_MAX];
536 unsigned int basename_len = 0;
537
538 strncpy(basename, nest_name, PATH_MAX);
539 basename_len = strlen(basename);
540
541 /* For a named type, we use the type_name directly */
542 if(td->type_name != NULL) {
543 strncpy(basename, td->type_name, PATH_MAX);
544 basename_len = strlen(basename);
a67cd958 545 } else {
a3e6ce64 546 /* For a unnamed type, there must be a field name, except for
547 * the array. */
548 if((basename_len != 0)
549 && (basename[basename_len-1] != '_'
34c1d1b5 550 && field_name != NULL
a3e6ce64 551 && (field_name[0] != '\0'))) {
552 strncat(basename, "_", PATH_MAX - basename_len);
553 basename_len = strlen(basename);
a67cd958 554 }
34c1d1b5 555 if(field_name != NULL)
556 strncat(basename, field_name, PATH_MAX - basename_len);
a67cd958 557 }
a3e6ce64 558
3d9b9b0c 559 if(field_name[0] == '\0') {
560 /* We are in a write function : it's the obj that we must align. */
561 switch(td->type) {
562 case SEQUENCE:
3261899d 563 fprintf(fd, "lttng_get_alignment_sequence_%s(%s)", basename,
564 obj_prefix);
3d9b9b0c 565 break;
566 case STRUCT:
3261899d 567 fprintf(fd, "lttng_get_alignment_struct_%s(%s)", basename,
568 obj_prefix);
3d9b9b0c 569 break;
570 case UNION:
3261899d 571 fprintf(fd, "lttng_get_alignment_union_%s(%s)", basename,
572 obj_prefix);
3d9b9b0c 573 break;
574 case ARRAY:
3261899d 575 fprintf(fd, "lttng_get_alignment_array_%s(%s)", basename,
576 obj_prefix);
a2ff13ed 577 case STRING:
578 fprintf(fd, "sizeof(char)");
3d9b9b0c 579 break;
8f78c30f 580 case INT_FIXED:
581 case UINT_FIXED:
582 case CHAR:
583 case UCHAR:
584 case SHORT:
585 case USHORT:
586 case INT:
587 case UINT:
588 case FLOAT:
589 case POINTER:
590 case LONG:
591 case ULONG:
592 case SIZE_T:
593 case SSIZE_T:
594 case OFF_T:
595 case ENUM:
596 fprintf(fd, "sizeof(");
597 if(print_type(td, fd, 0, basename, "")) return 1;
598 fprintf(fd, ")");
599 break;
600
3d9b9b0c 601 default:
602 printf("error : type unexpected\n");
603 return 1;
604 break;
605 }
606 } else {
607
608 switch(td->type) {
609 case INT_FIXED:
610 case UINT_FIXED:
611 case CHAR:
612 case UCHAR:
613 case SHORT:
614 case USHORT:
615 case INT:
616 case UINT:
617 case FLOAT:
618 case POINTER:
619 case LONG:
620 case ULONG:
621 case SIZE_T:
622 case SSIZE_T:
623 case OFF_T:
624 case ENUM:
625 fprintf(fd, "sizeof(");
626 if(print_type(td, fd, 0, basename, "")) return 1;
627 fprintf(fd, ")");
628 break;
629 case STRING:
630 fprintf(fd, "sizeof(char)");
631 break;
632 case SEQUENCE:
3261899d 633 fprintf(fd, "lttng_get_alignment_sequence_%s(&%s%s)", basename,
634 obj_prefix, field_name);
3d9b9b0c 635 break;
636 case STRUCT:
3261899d 637 fprintf(fd, "lttng_get_alignment_struct_%s(&%s%s)", basename,
638 obj_prefix, field_name);
3d9b9b0c 639 break;
640 case UNION:
3261899d 641 fprintf(fd, "lttng_get_alignment_union_%s(&%s%s)", basename,
642 obj_prefix, field_name);
3d9b9b0c 643 break;
644 case ARRAY:
3261899d 645 fprintf(fd, "lttng_get_alignment_array_%s(%s%s)", basename,
646 obj_prefix, field_name);
3d9b9b0c 647 break;
648 case NONE:
649 printf("error : type NONE unexpected\n");
650 return 1;
651 break;
652 }
a3e6ce64 653 }
3d9b9b0c 654
a3e6ce64 655 return 0;
a67cd958 656}
657
a3e6ce64 658/* print type write.
659 *
660 * Copied from construct_types_and_fields in LTTV facility.c
661 *
662 * basename is the name which identifies the type (along with a prefix
663 * (possibly)). */
a67cd958 664
a3e6ce64 665int print_type_write(type_descriptor_t * td, FILE *fd, unsigned int tabs,
458989d8 666 char *nest_name, char *field_name, char *obj_prefix, int get_ptr)
a67cd958 667{
a67cd958 668 char basename[PATH_MAX];
669 unsigned int basename_len = 0;
458989d8 670 char get_ptr_char[2] = "";
64a6ab10 671 char custom[PATH_MAX] = "";
a3e6ce64 672
673 strncpy(basename, nest_name, PATH_MAX);
a67cd958 674 basename_len = strlen(basename);
675
676 /* For a named type, we use the type_name directly */
677 if(td->type_name != NULL) {
678 strncpy(basename, td->type_name, PATH_MAX);
679 basename_len = strlen(basename);
680 } else {
a3e6ce64 681 /* For a unnamed type, there must be a field name, except for
682 * the array. */
a67cd958 683 if((basename_len != 0)
a3e6ce64 684 && (basename[basename_len-1] != '_'
685 && (field_name[0] != '\0'))) {
a67cd958 686 strncat(basename, "_", PATH_MAX - basename_len);
687 basename_len = strlen(basename);
688 }
689 strncat(basename, field_name, PATH_MAX - basename_len);
690 }
691
458989d8 692 if(get_ptr) {
693 strcpy(get_ptr_char, "&");
694 }
695
64a6ab10 696 if(td->custom_write) {
697 strcpy(custom, "_custom");
698 }
699
a67cd958 700 switch(td->type) {
701 case INT_FIXED:
702 case UINT_FIXED:
703 case CHAR:
704 case UCHAR:
705 case SHORT:
706 case USHORT:
707 case INT:
708 case UINT:
709 case FLOAT:
710 case POINTER:
711 case LONG:
712 case ULONG:
713 case SIZE_T:
714 case SSIZE_T:
715 case OFF_T:
716 case ENUM:
a67cd958 717 print_tabs(tabs, fd);
8f78c30f 718 fprintf(fd, "align = ");
719 if(print_type_alignment(td, fd, 0, basename, "", "obj")) return 1;
720 fprintf(fd, ";\n");
721 fprintf(fd, "\n");
722 print_tabs(tabs, fd);
723 fprintf(fd, "if(*len == 0) {\n");
724 print_tabs(tabs+1, fd);
725 fprintf(fd, "*to += ltt_align(*to, align); /* align output */\n");
726 print_tabs(tabs, fd);
727 fprintf(fd, "} else {\n");
728 print_tabs(tabs+1, fd);
729 fprintf(fd, "*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */\n");
730 print_tabs(tabs, fd);
731 fprintf(fd, "}\n");
732 fprintf(fd, "\n");
733
734 print_tabs(tabs, fd);
735 fprintf(fd, "*len += ");
a3e6ce64 736 fprintf(fd, "sizeof(");
2e415130 737 if(print_type(td, fd, 0, basename, "")) return 1;
a67cd958 738 fprintf(fd, ");\n");
8f78c30f 739
a67cd958 740 break;
741 case STRING:
a67cd958 742 print_tabs(tabs, fd);
3261899d 743 fprintf(fd,
64a6ab10 744 "lttng_write%s_string_%s(buffer, to_base, to, from, len, %s%s);\n",
745 custom, basename, obj_prefix, field_name);
a3e6ce64 746 break;
747 case SEQUENCE:
748 print_tabs(tabs, fd);
3261899d 749 fprintf(fd,
64a6ab10 750 "lttng_write%s_sequence_%s(buffer, to_base, to, from, len, %s%s%s);",
751 custom, basename, get_ptr_char, obj_prefix, field_name);
a3e6ce64 752 break;
753 case STRUCT:
754 print_tabs(tabs, fd);
3261899d 755 fprintf(fd,
64a6ab10 756 "lttng_write%s_struct_%s(buffer, to_base, to, from, len, %s%s%s);",
757 custom, basename, get_ptr_char, obj_prefix, field_name);
a3e6ce64 758 break;
759 case UNION:
760 print_tabs(tabs, fd);
3261899d 761 fprintf(fd,
64a6ab10 762 "lttng_write%s_union_%s(buffer, to_base, to, from, len, %s%s%s);",
763 custom, basename, get_ptr_char, obj_prefix, field_name);
a67cd958 764 break;
765 case ARRAY:
a67cd958 766 print_tabs(tabs, fd);
3261899d 767 fprintf(fd,
64a6ab10 768 "lttng_write%s_array_%s(buffer, to_base, to, from, len, %s%s);",
769 custom, basename, obj_prefix, field_name);
a3e6ce64 770 break;
2e415130 771 case NONE:
772 printf("Error : type NONE unexpected\n");
773 return 1;
774 break;
a3e6ce64 775 }
a67cd958 776
a3e6ce64 777 return 0;
778}
a67cd958 779
63c831c5 780/* print need local vars ?.
781 *
782 * Copied from print_type_write
783 *
784 * Does the type_write call needs local size and from variables ?
785 * return value : 1 yes, 0 no.
786 */
787
788int has_type_local(type_descriptor_t * td)
789{
790 switch(td->type) {
791 case INT_FIXED:
792 case UINT_FIXED:
793 case CHAR:
794 case UCHAR:
795 case SHORT:
796 case USHORT:
797 case INT:
798 case UINT:
799 case FLOAT:
800 case POINTER:
801 case LONG:
802 case ULONG:
803 case SIZE_T:
804 case SSIZE_T:
805 case OFF_T:
806 case ENUM:
807 return 1;
808 break;
809 case STRING:
810 case SEQUENCE:
811 case STRUCT:
812 case UNION:
813 case ARRAY:
814 return 0;
815 break;
816 case NONE:
817 printf("Error : type NONE unexpected\n");
818 return 1;
819 break;
820 }
821
822 return 0;
823}
824
a67cd958 825
a67cd958 826
a3e6ce64 827/* print type alignment function.
828 *
829 * Copied from construct_types_and_fields in LTTV facility.c
830 *
831 * basename is the name which identifies the type (along with a prefix
832 * (possibly)). */
833
834int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
835 unsigned int tabs,
836 char *nest_name, char *field_name)
837{
838 char basename[PATH_MAX];
839 unsigned int basename_len = 0;
840
64a6ab10 841 if(td->custom_write) return 0; /* Does print custom type */
842
a3e6ce64 843 strncpy(basename, nest_name, PATH_MAX);
844 basename_len = strlen(basename);
845
846 /* For a named type, we use the type_name directly */
847 if(td->type_name != NULL) {
848 strncpy(basename, td->type_name, PATH_MAX);
849 basename_len = strlen(basename);
850 } else {
851 /* For a unnamed type, there must be a field name, except for
852 * the array. */
853 if((basename_len != 0)
854 && (basename[basename_len-1] != '_'
855 && (field_name[0] != '\0'))) {
856 strncat(basename, "_", PATH_MAX - basename_len);
857 basename_len = strlen(basename);
858 }
859 strncat(basename, field_name, PATH_MAX - basename_len);
860 }
861
862 switch(td->type) {
863 case SEQUENCE:
ba899d3d 864 if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
865 /* Not a named nested type : we must print its align fct */
866 if(print_type_alignment_fct(((field_t*)td->fields.array[1])->type, fd,
867 0, basename, "")) return 1;
868 }
a3e6ce64 869 /* Function header */
870 fprintf(fd, "static inline size_t lttng_get_alignment_sequence_%s(\n",
871 basename);
872 print_tabs(2, fd);
2e415130 873 if(print_type(td, fd, 0, basename, "")) return 1;
a3e6ce64 874 fprintf(fd, " *obj)\n");
875 fprintf(fd, "{\n");
876 print_tabs(1, fd);
877 fprintf(fd, "size_t align=0, localign;");
878 fprintf(fd, "\n");
879 print_tabs(1, fd);
880 fprintf(fd, "localign = ");
881 if(print_type_alignment(((field_t*)td->fields.array[0])->type,
3261899d 882 fd, 0, basename, "len", "obj->")) return 1;
a3e6ce64 883 fprintf(fd, ";\n");
884 print_tabs(1, fd);
885 fprintf(fd, "align = max(align, localign);\n");
886 fprintf(fd, "\n");
887 print_tabs(1, fd);
888 fprintf(fd, "localign = ");
889 if(print_type_alignment(((field_t*)td->fields.array[1])->type,
3261899d 890 fd, 0, basename, "array[0]", "obj->")) return 1;
a3e6ce64 891 fprintf(fd, ";\n");
892 print_tabs(1, fd);
893 fprintf(fd, "align = max(align, localign);\n");
894 fprintf(fd, "\n");
895 print_tabs(1, fd);
896 fprintf(fd, "return align;\n");
897 break;
898 case STRUCT:
ba899d3d 899 for(unsigned int i=0;i<td->fields.position;i++){
900 field_t *field = (field_t*)(td->fields.array[i]);
901 type_descriptor_t *type = field->type;
902 if(type->type_name == NULL) {
903 /* Not a named nested type : we must print its align fct */
904 if(print_type_alignment_fct(type, fd,
905 0, basename, field->name)) return 1;
906 }
907 }
a3e6ce64 908 /* Function header */
909 fprintf(fd, "static inline size_t lttng_get_alignment_struct_%s(\n",
910 basename);
911 print_tabs(2, fd);
2e415130 912 if(print_type(td, fd, 0, basename, "")) return 1;
a3e6ce64 913 fprintf(fd, " *obj)\n");
914 fprintf(fd, "{\n");
915 print_tabs(1, fd);
916 fprintf(fd, "size_t align=0, localign;");
917 fprintf(fd, "\n");
918 for(unsigned int i=0;i<td->fields.position;i++){
919 field_t *field = (field_t*)(td->fields.array[i]);
920 type_descriptor_t *type = field->type;
921 print_tabs(1, fd);
922 fprintf(fd, "localign = ");
3261899d 923 if(print_type_alignment(type, fd, 0, basename, field->name, "obj->"))
924 return 1;
a3e6ce64 925 fprintf(fd, ";\n");
926 print_tabs(1, fd);
927 fprintf(fd, "align = max(align, localign);\n");
928 fprintf(fd, "\n");
929 }
930 print_tabs(1, fd);
931 fprintf(fd, "return align;\n");
932
a67cd958 933 break;
a3e6ce64 934 case UNION:
ba899d3d 935 for(unsigned int i=0;i<td->fields.position;i++){
936 field_t *field = (field_t*)(td->fields.array[i]);
937 type_descriptor_t *type = field->type;
938 if(type->type_name == NULL) {
939 /* Not a named nested type : we must print its align fct */
940 if(print_type_alignment_fct(type, fd,
941 0, basename, field->name)) return 1;
942 }
943 }
a3e6ce64 944 /* Function header */
945 fprintf(fd, "static inline size_t lttng_get_alignment_union_%s(\n",
946 basename);
947 print_tabs(2, fd);
2e415130 948 if(print_type(td, fd, 0, basename, "")) return 1;
a3e6ce64 949 fprintf(fd, " *obj)\n");
950 fprintf(fd, "{\n");
951 print_tabs(1, fd);
952 fprintf(fd, "size_t align=0, localign;");
953 fprintf(fd, "\n");
954 for(unsigned int i=0;i<td->fields.position;i++){
955 field_t *field = (field_t*)(td->fields.array[i]);
956 type_descriptor_t *type = field->type;
957 print_tabs(1, fd);
958 fprintf(fd, "localign = ");
3261899d 959 if(print_type_alignment(type, fd, 0, basename, field->name, "obj->"))
960 return 1;
a3e6ce64 961 fprintf(fd, ";\n");
962 print_tabs(1, fd);
963 fprintf(fd, "align = max(align, localign);\n");
964 fprintf(fd, "\n");
965 }
966 print_tabs(1, fd);
967 fprintf(fd, "return align;\n");
968
969 break;
970 case ARRAY:
ba899d3d 971 if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
972 /* Not a named nested type : we must print its align fct */
973 if(print_type_alignment_fct(((field_t*)td->fields.array[0])->type, fd,
974 0, basename, "")) return 1;
975 }
a3e6ce64 976 /* Function header */
977 fprintf(fd, "static inline size_t lttng_get_alignment_array_%s(\n",
978 basename);
979 print_tabs(2, fd);
2e415130 980 if(print_type(td, fd, 0, basename, "")) return 1;
a3e6ce64 981 fprintf(fd, " obj)\n");
982 fprintf(fd, "{\n");
983 print_tabs(1, fd);
984 fprintf(fd, "return \n");
985 if(print_type_alignment(((field_t*)td->fields.array[0])->type,
3261899d 986 fd, 0, basename, "", "obj[0]"))
987 return 1;
a3e6ce64 988 fprintf(fd, ";\n");
989 break;
990 default:
71e09db9 991 dprintf("print_type_alignment_fct : type has no alignment function.\n");
34c1d1b5 992 return 0;
a3e6ce64 993 break;
994 }
995
996
997 /* Function footer */
998 fprintf(fd, "}\n");
999 fprintf(fd, "\n");
1000
2e415130 1001 return 0;
a3e6ce64 1002}
1003
1004/* print type write function.
1005 *
1006 * Copied from construct_types_and_fields in LTTV facility.c
1007 *
1008 * basename is the name which identifies the type (along with a prefix
1009 * (possibly)). */
1010
1011int print_type_write_fct(type_descriptor_t * td, FILE *fd, unsigned int tabs,
1012 char *nest_name, char *field_name)
1013{
1014 char basename[PATH_MAX];
1015 unsigned int basename_len = 0;
1016
64a6ab10 1017 if(td->custom_write) return 0; /* Does print custom type */
1018
a3e6ce64 1019 strncpy(basename, nest_name, PATH_MAX);
1020 basename_len = strlen(basename);
1021
1022 /* For a named type, we use the type_name directly */
1023 if(td->type_name != NULL) {
1024 strncpy(basename, td->type_name, PATH_MAX);
1025 basename_len = strlen(basename);
1026 } else {
1027 /* For a unnamed type, there must be a field name, except for
1028 * the array. */
1029 if((basename_len != 0)
1030 && (basename[basename_len-1] != '_'
1031 && (field_name[0] != '\0'))) {
1032 strncat(basename, "_", PATH_MAX - basename_len);
1033 basename_len = strlen(basename);
1034 }
1035 strncat(basename, field_name, PATH_MAX - basename_len);
1036 }
1037
34c1d1b5 1038 switch(td->type) {
1039 case SEQUENCE:
ba899d3d 1040 if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
1041 /* Not a named nested type : we must print its write fct */
1042 if(print_type_write_fct(((field_t*)td->fields.array[1])->type, fd,
1043 0, basename, "")) return 1;
1044 }
1045 break;
34c1d1b5 1046 case STRUCT:
ba899d3d 1047 for(unsigned int i=0;i<td->fields.position;i++){
1048 field_t *field = (field_t*)(td->fields.array[i]);
1049 type_descriptor_t *type = field->type;
1050 if(type->type_name == NULL) {
1051 /* Not a named nested type : we must print its write fct */
1052 if(print_type_write_fct(type, fd,
1053 0, basename, field->name)) return 1;
1054 }
1055 }
1056 break;
34c1d1b5 1057 case UNION:
ba899d3d 1058 for(unsigned int i=0;i<td->fields.position;i++){
1059 field_t *field = (field_t*)(td->fields.array[i]);
1060 type_descriptor_t *type = field->type;
1061 if(type->type_name == NULL) {
1062 /* Not a named nested type : we must print its write fct */
1063 if(print_type_write_fct(type, fd,
1064 0, basename, field->name)) return 1;
1065 }
1066 }
1067 break;
34c1d1b5 1068 case ARRAY:
ba899d3d 1069 if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
1070 /* Not a named nested type : we must print its write fct */
1071 if(print_type_write_fct(((field_t*)td->fields.array[0])->type, fd,
1072 0, basename, "")) return 1;
1073 }
1074 break;
a2ff13ed 1075 case STRING:
34c1d1b5 1076 break;
1077 default:
71e09db9 1078 dprintf("print_type_write_fct : type has no write function.\n");
34c1d1b5 1079 return 0;
1080 break;
1081 }
1082
a3e6ce64 1083 /* Print header */
1084 switch(td->type) {
a67cd958 1085 case SEQUENCE:
34c1d1b5 1086 fprintf(fd, "static inline void lttng_write_sequence_%s(\n",
a3e6ce64 1087 basename);
a67cd958 1088 break;
a3e6ce64 1089 case STRUCT:
6e27ba88 1090 fprintf(fd, "static inline void lttng_write_struct_%s(\n", basename);
a67cd958 1091 break;
a3e6ce64 1092 case UNION:
6e27ba88 1093 fprintf(fd, "static inline void lttng_write_union_%s(\n", basename);
a3e6ce64 1094 break;
1095 case ARRAY:
6e27ba88 1096 fprintf(fd, "static inline void lttng_write_array_%s(\n", basename);
a3e6ce64 1097 break;
a2ff13ed 1098 case STRING:
1099 fprintf(fd, "static inline void lttng_write_string_%s(\n", basename);
1100 break;
a3e6ce64 1101 default:
1102 printf("print_type_write_fct : type has no write function.\n");
a67cd958 1103 break;
a67cd958 1104 }
1105
a3e6ce64 1106 print_tabs(2, fd);
59a957df 1107 fprintf(fd, "char *buffer,\n");
a3e6ce64 1108 print_tabs(2, fd);
1109 fprintf(fd, "size_t *to_base,\n");
1110 print_tabs(2, fd);
1111 fprintf(fd, "size_t *to,\n");
1112 print_tabs(2, fd);
59a957df 1113 fprintf(fd, "const char **from,\n");
a3e6ce64 1114 print_tabs(2, fd);
1115 fprintf(fd, "size_t *len,\n");
1116 print_tabs(2, fd);
2e415130 1117 if(print_type(td, fd, 0, basename, "")) return 1;
a3e6ce64 1118
1119 switch(td->type) {
1120 case SEQUENCE:
1121 fprintf(fd, " *obj)\n");
1122 break;
1123 case STRUCT:
1124 fprintf(fd, " *obj)\n");
1125 break;
1126 case UNION:
1127 fprintf(fd, " *obj)\n");
1128 break;
1129 case ARRAY:
1130 fprintf(fd, " obj)\n");
1131 break;
a2ff13ed 1132 case STRING:
1133 fprintf(fd, " obj)\n");
1134 break;
a3e6ce64 1135 default:
1136 printf("print_type_write_fct : type has no write function.\n");
1137 break;
1138 }
1139
1140 fprintf(fd, "{\n");
3ace7bc4 1141
f5f2fde4 1142 switch(td->type) {
1143 case STRING:
1144 print_tabs(1, fd);
1145 fprintf(fd, "size_t size;\n");
1146 break;
1147 default:
1148 break;
1149 }
1150
a3e6ce64 1151 print_tabs(1, fd);
3ace7bc4 1152 fprintf(fd, "size_t align;\n");
a3e6ce64 1153 fprintf(fd, "\n");
1154
1155 switch(td->type) {
1156 case SEQUENCE:
1157 case STRING:
1158 print_tabs(1, fd);
1159 fprintf(fd, "/* Flush pending memcpy */\n");
1160 print_tabs(1, fd);
1161 fprintf(fd, "if(*len != 0) {\n");
1162 print_tabs(2, fd);
1163 fprintf(fd, "if(buffer != NULL)\n");
1164 print_tabs(3, fd);
1165 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
1166 print_tabs(1, fd);
1167 fprintf(fd, "}\n");
1168 print_tabs(1, fd);
1169 fprintf(fd, "*to += *len;\n");
1170 print_tabs(1, fd);
1171 fprintf(fd, "*len = 0;\n");
1172 fprintf(fd, "\n");
1173 break;
1174 case STRUCT:
1175 case UNION:
1176 case ARRAY:
1177 break;
1178 default:
1179 printf("print_type_write_fct : type has no write function.\n");
1180 break;
1181 }
1182
1183 print_tabs(1, fd);
34c1d1b5 1184 fprintf(fd, "align = ");
0231ef76 1185 if(print_type_alignment(td, fd, 0, basename, "", "obj")) return 1;
a3e6ce64 1186 fprintf(fd, ";\n");
1187 fprintf(fd, "\n");
1188 print_tabs(1, fd);
1189 fprintf(fd, "if(*len == 0) {\n");
1190 print_tabs(2, fd);
1191 fprintf(fd, "*to += ltt_align(*to, align); /* align output */\n");
1192 print_tabs(1, fd);
1193 fprintf(fd, "} else {\n");
1194 print_tabs(2, fd);
1195 fprintf(fd, "*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */\n");
1196 print_tabs(1, fd);
1197 fprintf(fd, "}\n");
1198 fprintf(fd, "\n");
1199
1200 /* First, check if the type has a fixed size. If it is the case, then the size
1201 * to write is know by the compiler : simply use a sizeof() */
1202 if(has_type_fixed_size(td)) {
1203 print_tabs(1, fd);
1204 fprintf(fd, "/* Contains only fixed size fields : use compiler sizeof() */\n");
1205 fprintf(fd, "\n");
1206 print_tabs(1, fd);
f5f2fde4 1207 fprintf(fd, "*len += sizeof(");
2e415130 1208 if(print_type(td, fd, 0, basename, field_name)) return 1;
a3e6ce64 1209 fprintf(fd, ");\n");
1210 } else {
1211 /* The type contains nested variable size subtypes :
1212 * we must write field by field. */
1213 print_tabs(1, fd);
1214 fprintf(fd, "/* Contains variable sized fields : must explode the structure */\n");
1215 fprintf(fd, "\n");
1216
1217 switch(td->type) {
1218 case SEQUENCE:
1219 print_tabs(1, fd);
1220 fprintf(fd, "/* Copy members */\n");
3261899d 1221// print_tabs(1, fd);
1222// fprintf(fd, "size = sizeof(\n");
a3e6ce64 1223 if(print_type_write(((field_t*)td->fields.array[0])->type,
458989d8 1224 fd, 1, basename, "len", "obj->", 1)) return 1;
3261899d 1225 fprintf(fd, "\n");
1226// fprintf(fd, ");\n");
1227// print_tabs(1, fd);
1228// fprintf(fd, "*to += ltt_align(*to, size);\n");
a3e6ce64 1229 print_tabs(1, fd);
1230 fprintf(fd, "if(buffer != NULL)\n");
1231 print_tabs(2, fd);
8f78c30f 1232 fprintf(fd, "memcpy(buffer+*to_base+*to, &obj->len, *len);\n");
a3e6ce64 1233 print_tabs(1, fd);
8f78c30f 1234 fprintf(fd, "*to += *len;\n");
1235 print_tabs(1, fd);
1236 fprintf(fd, "*len = 0;\n");
a3e6ce64 1237 fprintf(fd, "\n");
8f78c30f 1238
a3e6ce64 1239 /* Write the child : varlen child or not ? */
1240 if(has_type_fixed_size(((field_t*)td->fields.array[1])->type)) {
1241 /* Fixed size len child : use a multiplication of its size */
3261899d 1242// print_tabs(1, fd);
1243// fprintf(fd, "size = sizeof(\n");
8f78c30f 1244
1245 //print_tabs(1, fd);
1246 /* We know that *len does not contain alignment because of the
1247 * previous align output. len is always 0 here. */
a3e6ce64 1248 if(print_type_write(((field_t*)td->fields.array[1])->type,
8f78c30f 1249 fd, 1, basename, "array[0]", "obj->", 1))
1250 return 1;
3261899d 1251// fprintf(fd, ");\n");
8f78c30f 1252 fprintf(fd, "\n");
a3e6ce64 1253 print_tabs(1, fd);
8f78c30f 1254 fprintf(fd, "*len = obj->len * (*len);\n");
a3e6ce64 1255 print_tabs(1, fd);
1256 fprintf(fd, "if(buffer != NULL)\n");
1257 print_tabs(2, fd);
8f78c30f 1258 fprintf(fd, "memcpy(buffer+*to_base+*to, obj->array, *len);\n");
1259 print_tabs(1, fd);
1260 fprintf(fd, "*to += *len;\n");
a3e6ce64 1261 print_tabs(1, fd);
8f78c30f 1262 fprintf(fd, "*len = 0;\n");
a3e6ce64 1263 fprintf(fd, "\n");
1264 } else {
1265 print_tabs(1, fd);
1266 fprintf(fd, "/* Variable length child : iter. */\n");
1267 print_tabs(1, fd);
1268 fprintf(fd, "for(unsigned int i=0; i<obj->len; i++) {\n");
1269 if(print_type_write(((field_t*)td->fields.array[1])->type,
458989d8 1270 fd, 2, basename, "array[i]", "obj->", 1)) return 1;
a3e6ce64 1271 print_tabs(1, fd);
1272 fprintf(fd, "}\n");
1273 }
1274 fprintf(fd, "\n");
1275 print_tabs(1, fd);
1276 fprintf(fd, "/* Realign the *to_base on arch size, set *to to 0 */\n");
1277 print_tabs(1, fd);
2a5eec7d 1278 fprintf(fd, "*to += ltt_align(*to, sizeof(void *));\n");
a3e6ce64 1279 print_tabs(1, fd);
1280 fprintf(fd, "*to_base = *to_base+*to;\n");
1281 print_tabs(1, fd);
1282 fprintf(fd, "*to = 0;\n");
1283 fprintf(fd, "\n");
a2ff13ed 1284 print_tabs(1, fd);
a3e6ce64 1285 fprintf(fd, "/* Put source *from just after the C sequence */\n");
1286 print_tabs(1, fd);
1287 fprintf(fd, "*from = obj+1;\n");
1288 break;
1289 case STRING:
a2ff13ed 1290 print_tabs(1, fd);
caabcb43 1291 fprintf(fd, "size = strlen(obj) + 1; /* Include final NULL char. */\n");
a3e6ce64 1292 print_tabs(1, fd);
1293 fprintf(fd, "if(buffer != NULL)\n");
1294 print_tabs(2, fd);
1295 fprintf(fd, "memcpy(buffer+*to_base+*to, obj, size);\n");
1296 print_tabs(1, fd);
1297 fprintf(fd, "*to += size;\n");
1298 fprintf(fd, "\n");
1299 print_tabs(1, fd);
1300 fprintf(fd, "/* Realign the *to_base on arch size, set *to to 0 */\n");
1301 print_tabs(1, fd);
2a5eec7d 1302 fprintf(fd, "*to += ltt_align(*to, sizeof(void *));\n");
a3e6ce64 1303 print_tabs(1, fd);
1304 fprintf(fd, "*to_base = *to_base+*to;\n");
1305 print_tabs(1, fd);
1306 fprintf(fd, "*to = 0;\n");
1307 fprintf(fd, "\n");
a3e6ce64 1308 print_tabs(1, fd);
a2ff13ed 1309 fprintf(fd, "/* Put source *from just after the C string */\n");
1310 print_tabs(1, fd);
1311 fprintf(fd, "*from += size;\n");
a3e6ce64 1312 break;
1313 case STRUCT:
1314 for(unsigned int i=0;i<td->fields.position;i++){
1315 field_t *field = (field_t*)(td->fields.array[i]);
1316 type_descriptor_t *type = field->type;
1317 if(print_type_write(type,
458989d8 1318 fd, 1, basename, field->name, "obj->", 1)) return 1;
a3e6ce64 1319 fprintf(fd, "\n");
1320 }
1321 break;
1322 case UNION:
1323 printf("ERROR : A union CANNOT contain a variable size child.\n");
1324 return 1;
1325 break;
1326 case ARRAY:
1327 /* Write the child : varlen child or not ? */
1328 if(has_type_fixed_size(((field_t*)td->fields.array[0])->type)) {
1329 /* Error : if an array has a variable size, then its child must also
1330 * have a variable size. */
1331 assert(0);
1332 } else {
1333 print_tabs(1, fd);
1334 fprintf(fd, "/* Variable length child : iter. */\n");
1335 print_tabs(1, fd);
1336 fprintf(fd, "for(unsigned int i=0; i<LTTNG_ARRAY_SIZE_%s; i++) {\n", basename);
3261899d 1337 if(print_type_write(((field_t*)td->fields.array[0])->type,
458989d8 1338 fd, 2, basename, "", "obj->array[i]", 1)) return 1;
a3e6ce64 1339 print_tabs(1, fd);
1340 fprintf(fd, "}\n");
1341 }
1342 break;
1343 default:
1344 printf("print_type_write_fct : type has no write function.\n");
1345 break;
1346 }
1347
1348
1349 }
1350
1351
1352 /* Function footer */
1353 fprintf(fd, "}\n");
1354 fprintf(fd, "\n");
a67cd958 1355 return 0;
1356}
1357
1358
1359
47299663 1360/* Print the logging function of an event. This is the core of genevent */
a3e6ce64 1361int print_event_logging_function(char *basename, facility_t *fac,
1362 event_t *event, FILE *fd)
47299663 1363{
1364 fprintf(fd, "static inline void trace_%s(\n", basename);
3d9b9b0c 1365 int has_argument = 0;
63c831c5 1366 int has_type_fixed = 0;
3d9b9b0c 1367
1368 /* Does it support per trace tracing ? */
1369 if(event->per_trace) {
1370 print_tabs(2, fd);
1371 fprintf(fd, "struct ltt_trace_struct *dest_trace");
1372 has_argument = 1;
1373 }
1374
1375 /* Does it support per tracefile tracing ? */
1376 if(event->per_tracefile) {
1377 if(has_argument) {
1378 fprintf(fd, ",");
1379 fprintf(fd, "\n");
1380 }
1381 fprintf(fd, "unsigned int tracefile_index");
1382 has_argument = 1;
1383 }
1384
47299663 1385 for(unsigned int j = 0; j < event->fields.position; j++) {
1386 /* For each field, print the function argument */
1387 field_t *f = (field_t*)event->fields.array[j];
1388 type_descriptor_t *t = f->type;
3d9b9b0c 1389 if(has_argument) {
47299663 1390 fprintf(fd, ",");
1391 fprintf(fd, "\n");
1392 }
3d9b9b0c 1393 if(print_arg(t, fd, 2, basename, f->name)) return 1;
1394 has_argument = 1;
47299663 1395 }
3d9b9b0c 1396 if(!has_argument) {
47299663 1397 print_tabs(2, fd);
1398 fprintf(fd, "void");
1399 }
1400 fprintf(fd,")\n");
71e09db9 1401 fprintf(fd,
1402 "#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_%s))\n",
1403 fac->capname);
47299663 1404 fprintf(fd, "{\n");
1405 fprintf(fd, "}\n");
1406 fprintf(fd,"#else\n");
1407 fprintf(fd, "{\n");
7e97b039 1408 /* Print the function variables */
a67cd958 1409 print_tabs(1, fd);
a3e6ce64 1410 fprintf(fd, "unsigned int index;\n");
1411 print_tabs(1, fd);
1412 fprintf(fd, "struct ltt_channel_struct *channel;\n");
1413 print_tabs(1, fd);
1414 fprintf(fd, "struct ltt_trace_struct *trace;\n");
1415 print_tabs(1, fd);
db6c25a6 1416 fprintf(fd, "void *transport_data;\n");
a3e6ce64 1417 print_tabs(1, fd);
59a957df 1418 fprintf(fd, "char *buffer = NULL;\n");
a3e6ce64 1419 print_tabs(1, fd);
458989d8 1420 fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
1421 print_tabs(1, fd);
1422 fprintf(fd, "size_t *to_base = &real_to_base;\n");
a3e6ce64 1423 print_tabs(1, fd);
458989d8 1424 fprintf(fd, "size_t real_to = 0;\n");
a3e6ce64 1425 print_tabs(1, fd);
458989d8 1426 fprintf(fd, "size_t *to = &real_to;\n");
a3e6ce64 1427 print_tabs(1, fd);
458989d8 1428 fprintf(fd, "size_t real_len = 0;\n");
1429 print_tabs(1, fd);
1430 fprintf(fd, "size_t *len = &real_len;\n");
30d72138 1431 print_tabs(1, fd);
6e27ba88 1432 fprintf(fd, "size_t reserve_size;\n");
1433 print_tabs(1, fd);
a3e6ce64 1434 fprintf(fd, "size_t slot_size;\n");
30d72138 1435 print_tabs(1, fd);
63c831c5 1436
ac963fe3 1437 if(event->fields.position > 0) {
63c831c5 1438 for(unsigned int i=0;i<event->fields.position;i++){
1439 /* Search for at least one child with fixed size. It means
1440 * we need local variables.*/
1441 field_t *field = (field_t*)(event->fields.array[i]);
1442 type_descriptor_t *type = field->type;
1443 has_type_fixed = has_type_local(type);
1444 if(has_type_fixed) break;
1445 }
1446
1447 if(has_type_fixed) {
8f78c30f 1448 fprintf(fd, "size_t align;\n");
63c831c5 1449 print_tabs(1, fd);
1450 }
1451
59a957df 1452 fprintf(fd, "const char *real_from;\n");
ac963fe3 1453 print_tabs(1, fd);
59a957df 1454 fprintf(fd, "const char **from = &real_from;\n");
ac963fe3 1455 print_tabs(1, fd);
1456 }
8e290e8b 1457 fprintf(fd, "u64 tsc;\n");
30d72138 1458 print_tabs(1, fd);
458989d8 1459 fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n");
a3e6ce64 1460 fprintf(fd, "\n");
7e97b039 1461
a3e6ce64 1462 print_tabs(1, fd);
1463 fprintf(fd, "if(ltt_traces.num_active_traces == 0) return;\n");
1464 fprintf(fd, "\n");
1465
a67cd958 1466 /* Calculate event variable len + event data alignment offset.
7e97b039 1467 * Assume that the padding for alignment starts at a void*
a67cd958 1468 * address.
1469 * This excludes the header size and alignment. */
1470
a3e6ce64 1471 print_tabs(1, fd);
1472 fprintf(fd, "/* For each field, calculate the field size. */\n");
1473 print_tabs(1, fd);
458989d8 1474 fprintf(fd, "/* size = *to_base + *to + *len */\n");
a3e6ce64 1475 print_tabs(1, fd);
30d72138 1476 fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
a3e6ce64 1477 print_tabs(1, fd);
30d72138 1478 fprintf(fd, " * sizeof(void *) address. */\n");
a3e6ce64 1479 fprintf(fd, "\n");
a67cd958 1480
a3e6ce64 1481 for(unsigned int i=0;i<event->fields.position;i++){
2e415130 1482 field_t *field = (field_t*)(event->fields.array[i]);
a3e6ce64 1483 type_descriptor_t *type = field->type;
458989d8 1484 /* Set from */
1485 print_tabs(1, fd);
1486 switch(type->type) {
1487 case SEQUENCE:
1488 case UNION:
1489 case ARRAY:
1490 case STRUCT:
1491 case STRING:
3ace7bc4 1492 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
458989d8 1493 break;
1494 default:
3ace7bc4 1495 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
458989d8 1496 break;
1497 }
1498
a3e6ce64 1499 if(print_type_write(type,
3ace7bc4 1500 fd, 1, basename, field->name, "lttng_param_", 0)) return 1;
a3e6ce64 1501 fprintf(fd, "\n");
a67cd958 1502 }
6e27ba88 1503 print_tabs(1, fd);
458989d8 1504 fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
47299663 1505
7e97b039 1506 /* Take locks : make sure the trace does not vanish while we write on
1507 * it. A simple preemption disabling is enough (using rcu traces). */
a3e6ce64 1508 print_tabs(1, fd);
1509 fprintf(fd, "preempt_disable();\n");
1510 print_tabs(1, fd);
358f8354 1511 fprintf(fd, "ltt_nesting[smp_processor_id()]++;\n");
a3e6ce64 1512
1513 /* Get facility index */
1514
1515 if(event->per_tracefile) {
1516 print_tabs(1, fd);
1517 fprintf(fd, "index = tracefile_index;\n");
1518 } else {
1519 print_tabs(1, fd);
1520 fprintf(fd,
1521 "index = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
458989d8 1522 "\t\t\t\t\t\tevent_%s_%s);\n",
1523 fac->name, fac->checksum, fac->name, event->name);
a3e6ce64 1524 }
1525 fprintf(fd,"\n");
1526
7e97b039 1527
1528 /* For each trace */
a3e6ce64 1529 print_tabs(1, fd);
1530 fprintf(fd, "list_for_each_entry_rcu(trace, &ltt_traces.head, list) {\n");
1531 print_tabs(2, fd);
1532 fprintf(fd, "if(!trace->active) continue;\n\n");
1533
1534 if(event->per_trace) {
1535 print_tabs(2, fd);
1536 fprintf(fd, "if(dest_trace != trace) continue;\n\n");
1537 }
1538
1539 print_tabs(2, fd);
2e415130 1540 fprintf(fd, "channel = ltt_get_channel_from_index(trace, index);\n");
a3e6ce64 1541 fprintf(fd, "\n");
1542
7e97b039 1543
1544 /* Relay reserve */
a3e6ce64 1545 /* If error, increment event lost counter (done by ltt_reserve_slot) and
1546 * return */
1547 print_tabs(2, fd);
1548 fprintf(fd, "slot_size = 0;\n");
1549 print_tabs(2, fd);
db6c25a6 1550 fprintf(fd, "buffer = ltt_reserve_slot(trace, channel, &transport_data,\n");
30d72138 1551 print_tabs(3, fd);
6e27ba88 1552 fprintf(fd, "reserve_size, &slot_size, &tsc,\n");
30d72138 1553 print_tabs(3, fd);
458989d8 1554 fprintf(fd, "&before_hdr_pad, &after_hdr_pad, &header_size);\n");
a3e6ce64 1555 /* If error, return */
1556 print_tabs(2, fd);
43f7f14f 1557 fprintf(fd, "if(!buffer) continue; /* buffer full */\n\n");
8f78c30f 1558 //print_tabs(2, fd);
1559 // for DEBUG only
1560 // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n");
1561 print_tabs(2, fd);
1562 fprintf(fd, "*to_base = *to = *len = 0;\n");
1563 fprintf(fd, "\n");
1564
458989d8 1565 /* Write event header */
1566 print_tabs(2, fd);
1567 fprintf(fd, "ltt_write_event_header(trace, channel, buffer,\n");
1568 print_tabs(3, fd);
1569 fprintf(fd, "ltt_facility_%s_%X, event_%s_%s,\n", fac->name, fac->checksum,
1570 fac->name, event->name);
1571 print_tabs(3, fd);
1572 fprintf(fd, "reserve_size, before_hdr_pad, tsc);\n");
1573 print_tabs(2, fd);
1574 fprintf(fd, "*to_base += before_hdr_pad + after_hdr_pad + header_size;\n");
2a5eec7d 1575 fprintf(fd, "\n");
7e97b039 1576
8f78c30f 1577 /* write data. */
a3e6ce64 1578
1579 for(unsigned int i=0;i<event->fields.position;i++){
2e415130 1580 field_t *field = (field_t*)(event->fields.array[i]);
a3e6ce64 1581 type_descriptor_t *type = field->type;
8f78c30f 1582
a3e6ce64 1583 /* Set from */
30d72138 1584 print_tabs(2, fd);
1585 switch(type->type) {
1586 case SEQUENCE:
1587 case UNION:
1588 case ARRAY:
1589 case STRUCT:
1590 case STRING:
3ace7bc4 1591 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
30d72138 1592 break;
1593 default:
3ace7bc4 1594 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
30d72138 1595 break;
1596 }
1597
a3e6ce64 1598
1599 if(print_type_write(type,
3ace7bc4 1600 fd, 2, basename, field->name, "lttng_param_", 0)) return 1;
a3e6ce64 1601 fprintf(fd, "\n");
7e97b039 1602
a3e6ce64 1603 /* Don't forget to flush pending memcpy */
1604 print_tabs(2, fd);
1605 fprintf(fd, "/* Flush pending memcpy */\n");
1606 print_tabs(2, fd);
8f78c30f 1607 fprintf(fd, "if(*len != 0) {\n");
a3e6ce64 1608 print_tabs(3, fd);
458989d8 1609 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
a3e6ce64 1610 print_tabs(3, fd);
458989d8 1611 fprintf(fd, "*to += *len;\n");
a3e6ce64 1612 //print_tabs(3, fd);
1613 //fprintf(fd, "from += len;\n");
1614 print_tabs(3, fd);
458989d8 1615 fprintf(fd, "*len = 0;\n");
a3e6ce64 1616 print_tabs(2, fd);
1617 fprintf(fd, "}\n");
1618 fprintf(fd, "\n");
1619 }
1620
1621
7e97b039 1622 /* commit */
8f78c30f 1623 // for DEBUG only.
1624 //fprintf(fd, "commit:\n"); /* DEBUG! */
a3e6ce64 1625 print_tabs(2, fd);
db6c25a6 1626 fprintf(fd, "ltt_commit_slot(channel, &transport_data, buffer, slot_size);\n\n");
7e97b039 1627
a3e6ce64 1628 print_tabs(1, fd);
1629 fprintf(fd, "}\n\n");
1630
7e97b039 1631 /* Release locks */
a3e6ce64 1632 print_tabs(1, fd);
358f8354 1633 fprintf(fd, "ltt_nesting[smp_processor_id()]--;\n");
a3e6ce64 1634 print_tabs(1, fd);
1635 fprintf(fd, "preempt_enable_no_resched();\n");
2d2d14a7 1636
47299663 1637 fprintf(fd, "}\n");
71e09db9 1638 fprintf(fd, "#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_%s))\n\n",
1639 fac->capname);
47299663 1640 return 0;
1641}
2d2d14a7 1642
8a9103df 1643/* print_event_logging_function_user_generic
bd7b8ca6 1644 * Print the logging function of an event for userspace tracing. This is the
1645 * core of genevent */
8a9103df 1646int print_event_logging_function_user_generic(char *basename, facility_t *fac,
bd7b8ca6 1647 event_t *event, FILE *fd)
1648{
4a6829e2 1649 char *attrib;
8a9103df 1650
1651 fprintf(fd, "#ifndef LTT_TRACE_FAST\n");
1652
4a6829e2 1653 if(event->no_instrument_function) {
1654 attrib = "__attribute__((no_instrument_function)) ";
1655 } else {
1656 attrib = "";
1657 }
1e08067e 1658 if(event->param_buffer) {
4a6829e2 1659 fprintf(fd, "static inline %sint trace_%s_param_buffer(\n", attrib, basename);
1e08067e 1660 } else {
4a6829e2 1661 fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename);
1e08067e 1662 }
bd7b8ca6 1663 int has_argument = 0;
1664 int has_type_fixed = 0;
1665
1e08067e 1666 if(event->param_buffer) {
bd7b8ca6 1667 if(has_argument) {
1e08067e 1668 fprintf(fd, ",");
1669 fprintf(fd, "\n");
bd7b8ca6 1670 }
1e08067e 1671 print_tabs(2, fd);
59a957df 1672 fprintf(fd, "char *buffer");
bd7b8ca6 1673 has_argument = 1;
1e08067e 1674 fprintf(fd, ",");
1675 fprintf(fd, "\n");
1676 print_tabs(2, fd);
1677 fprintf(fd, "size_t reserve_size");
1678 } else {
1679 for(unsigned int j = 0; j < event->fields.position; j++) {
1680 /* For each field, print the function argument */
1681 field_t *f = (field_t*)event->fields.array[j];
1682 type_descriptor_t *t = f->type;
1683 if(has_argument) {
1684 fprintf(fd, ",");
1685 fprintf(fd, "\n");
1686 }
1687 if(print_arg(t, fd, 2, basename, f->name)) return 1;
1688 has_argument = 1;
1689 }
bd7b8ca6 1690 }
1691 if(!has_argument) {
1692 print_tabs(2, fd);
1693 fprintf(fd, "void");
1694 }
1695 fprintf(fd,")\n");
1696 fprintf(fd,
1697 "#ifndef LTT_TRACE\n");
1698 fprintf(fd, "{\n");
1699 fprintf(fd, "}\n");
1700 fprintf(fd,"#else\n");
1701 fprintf(fd, "{\n");
1702 /* Print the function variables */
1703 print_tabs(1, fd);
1e08067e 1704 fprintf(fd, "int ret = 0;\n");
1705 if(event->param_buffer) {
1706 print_tabs(1, fd);
1707 fprintf(fd, "reserve_size = ltt_align(reserve_size, sizeof(void *));\n");
1708 print_tabs(1, fd);
1709 fprintf(fd, "{\n");
1710 goto do_syscall;
1711 }
1712 print_tabs(1, fd);
59a957df 1713 fprintf(fd, "char *buffer = NULL;\n");
bd7b8ca6 1714 print_tabs(1, fd);
1715 fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
1716 print_tabs(1, fd);
1717 fprintf(fd, "size_t *to_base = &real_to_base;\n");
1718 print_tabs(1, fd);
1719 fprintf(fd, "size_t real_to = 0;\n");
1720 print_tabs(1, fd);
1721 fprintf(fd, "size_t *to = &real_to;\n");
1722 print_tabs(1, fd);
1723 fprintf(fd, "size_t real_len = 0;\n");
1724 print_tabs(1, fd);
1725 fprintf(fd, "size_t *len = &real_len;\n");
1726 print_tabs(1, fd);
1727 fprintf(fd, "size_t reserve_size;\n");
1728 print_tabs(1, fd);
1729 fprintf(fd, "size_t slot_size;\n");
1730 print_tabs(1, fd);
bd7b8ca6 1731
1732 if(event->fields.position > 0) {
1733 for(unsigned int i=0;i<event->fields.position;i++){
1734 /* Search for at least one child with fixed size. It means
1735 * we need local variables.*/
1736 field_t *field = (field_t*)(event->fields.array[i]);
1737 type_descriptor_t *type = field->type;
1738 has_type_fixed = has_type_local(type);
1739 if(has_type_fixed) break;
1740 }
1741
1742 if(has_type_fixed) {
1743 fprintf(fd, "size_t align;\n");
1744 print_tabs(1, fd);
1745 }
1746
59a957df 1747 fprintf(fd, "const char *real_from;\n");
bd7b8ca6 1748 print_tabs(1, fd);
59a957df 1749 fprintf(fd, "const char **from = &real_from;\n");
bd7b8ca6 1750 print_tabs(1, fd);
1751 }
1752
1753 /* Calculate event variable len + event data alignment offset.
1754 * Assume that the padding for alignment starts at a void*
1755 * address.
1756 * This excludes the header size and alignment. */
1757
1758 print_tabs(1, fd);
1759 fprintf(fd, "/* For each field, calculate the field size. */\n");
1760 print_tabs(1, fd);
1761 fprintf(fd, "/* size = *to_base + *to + *len */\n");
1762 print_tabs(1, fd);
1763 fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
1764 print_tabs(1, fd);
1765 fprintf(fd, " * sizeof(void *) address. */\n");
1766 fprintf(fd, "\n");
1767
1768 for(unsigned int i=0;i<event->fields.position;i++){
1769 field_t *field = (field_t*)(event->fields.array[i]);
1770 type_descriptor_t *type = field->type;
1771 /* Set from */
1772 print_tabs(1, fd);
1773 switch(type->type) {
1774 case SEQUENCE:
1775 case UNION:
1776 case ARRAY:
1777 case STRUCT:
1778 case STRING:
1779 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
1780 break;
1781 default:
1782 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
1783 break;
1784 }
1785
1786 if(print_type_write(type,
1787 fd, 1, basename, field->name, "lttng_param_", 0)) return 1;
1788 fprintf(fd, "\n");
1789 }
1790 print_tabs(1, fd);
1791 fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
1792
1793 print_tabs(1, fd);
1794 fprintf(fd, "{\n");
1795 print_tabs(2, fd);
1796 fprintf(fd, "char stack_buffer[reserve_size];\n");
1797 print_tabs(2, fd);
1798 fprintf(fd, "buffer = stack_buffer;\n");
1799 fprintf(fd, "\n");
1800
1801
1802 //print_tabs(2, fd);
1803 // for DEBUG only
1804 // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n");
1805 print_tabs(2, fd);
1806 fprintf(fd, "*to_base = *to = *len = 0;\n");
1807 fprintf(fd, "\n");
1808
1809 /* write data. */
1810
1811 for(unsigned int i=0;i<event->fields.position;i++){
1812 field_t *field = (field_t*)(event->fields.array[i]);
1813 type_descriptor_t *type = field->type;
1814
1815 /* Set from */
1816 print_tabs(2, fd);
1817 switch(type->type) {
1818 case SEQUENCE:
1819 case UNION:
1820 case ARRAY:
1821 case STRUCT:
1822 case STRING:
1823 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
1824 break;
1825 default:
1826 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
1827 break;
1828 }
1829
1830
1831 if(print_type_write(type,
1832 fd, 2, basename, field->name, "lttng_param_", 0)) return 1;
1833 fprintf(fd, "\n");
1834
1835 /* Don't forget to flush pending memcpy */
1836 print_tabs(2, fd);
1837 fprintf(fd, "/* Flush pending memcpy */\n");
1838 print_tabs(2, fd);
1839 fprintf(fd, "if(*len != 0) {\n");
1840 print_tabs(3, fd);
1841 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
1842 print_tabs(3, fd);
1843 fprintf(fd, "*to += *len;\n");
1844 //print_tabs(3, fd);
1845 //fprintf(fd, "from += len;\n");
1846 print_tabs(3, fd);
1847 fprintf(fd, "*len = 0;\n");
1848 print_tabs(2, fd);
1849 fprintf(fd, "}\n");
1850 fprintf(fd, "\n");
1851 }
1852
1e08067e 1853do_syscall:
bd7b8ca6 1854 print_tabs(2, fd);
1e08067e 1855 fprintf(fd, "ret = ltt_trace_generic(ltt_facility_%s_%X, event_%s_%s, buffer, reserve_size, LTT_BLOCKING);\n", fac->name, fac->checksum, fac->name, event->name);
bd7b8ca6 1856
1857 print_tabs(1, fd);
1858 fprintf(fd, "}\n\n");
1859
1860 print_tabs(1, fd);
1861 fprintf(fd, "return ret;\n\n");
1862
1863 fprintf(fd, "}\n");
1864 fprintf(fd,
1865 "#endif //LTT_TRACE\n");
8a9103df 1866 fprintf(fd, "#endif //!LTT_TRACE_FAST\n\n");
bd7b8ca6 1867
1868 return 0;
1869}
2d2d14a7 1870
8a9103df 1871/* print_event_logging_function_user_fast
1872 * Print the logging function of an event for userspace tracing. This is the
1873 * core of genevent */
1874int print_event_logging_function_user_fast(char *basename, facility_t *fac,
1875 event_t *event, FILE *fd)
1876{
1877 char *attrib;
1878
1879 fprintf(fd, "#ifdef LTT_TRACE_FAST\n");
1880
1881 if(event->no_instrument_function) {
1882 attrib = "__attribute__((no_instrument_function)) ";
1883 } else {
1884 attrib = "";
1885 }
1886 fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename);
1887
1888 int has_argument = 0;
1889 int has_type_fixed = 0;
1890
1891 for(unsigned int j = 0; j < event->fields.position; j++) {
1892 /* For each field, print the function argument */
1893 field_t *f = (field_t*)event->fields.array[j];
1894 type_descriptor_t *t = f->type;
1895 if(has_argument) {
1896 fprintf(fd, ",");
1897 fprintf(fd, "\n");
1898 }
1899 if(print_arg(t, fd, 2, basename, f->name)) return 1;
1900 has_argument = 1;
1901 }
1902 if(!has_argument) {
1903 print_tabs(2, fd);
1904 fprintf(fd, "void");
1905 }
1906 fprintf(fd,")\n");
1907 fprintf(fd,
1908 "#ifndef LTT_TRACE\n");
1909 fprintf(fd, "{\n");
1910 fprintf(fd, "}\n");
1911 fprintf(fd,"#else\n");
1912 fprintf(fd, "{\n");
1913 /* Print the function variables */
1914 print_tabs(1, fd);
1915 fprintf(fd, "unsigned int index;\n");
1916 print_tabs(1, fd);
1917 fprintf(fd, "struct ltt_trace_info *trace = thread_trace_info;\n");
1918 print_tabs(1, fd);
1919 fprintf(fd, "struct ltt_buf *ltt_buf;\n");
1920 print_tabs(1, fd);
59a957df 1921 fprintf(fd, "char *buffer = NULL;\n");
8a9103df 1922 print_tabs(1, fd);
1923 fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
1924 print_tabs(1, fd);
1925 fprintf(fd, "size_t *to_base = &real_to_base;\n");
1926 print_tabs(1, fd);
1927 fprintf(fd, "size_t real_to = 0;\n");
1928 print_tabs(1, fd);
1929 fprintf(fd, "size_t *to = &real_to;\n");
1930 print_tabs(1, fd);
1931 fprintf(fd, "size_t real_len = 0;\n");
1932 print_tabs(1, fd);
1933 fprintf(fd, "size_t *len = &real_len;\n");
1934 print_tabs(1, fd);
1935 fprintf(fd, "size_t reserve_size;\n");
1936 print_tabs(1, fd);
1937 fprintf(fd, "size_t slot_size;\n");
1938 print_tabs(1, fd);
1939
1940 if(event->fields.position > 0) {
1941 for(unsigned int i=0;i<event->fields.position;i++){
1942 /* Search for at least one child with fixed size. It means
1943 * we need local variables.*/
1944 field_t *field = (field_t*)(event->fields.array[i]);
1945 type_descriptor_t *type = field->type;
1946 has_type_fixed = has_type_local(type);
1947 if(has_type_fixed) break;
1948 }
1949
1950 if(has_type_fixed) {
1951 fprintf(fd, "size_t align;\n");
1952 print_tabs(1, fd);
1953 }
1954
59a957df 1955 fprintf(fd, "const char *real_from;\n");
8a9103df 1956 print_tabs(1, fd);
59a957df 1957 fprintf(fd, "const char **from = &real_from;\n");
8a9103df 1958 print_tabs(1, fd);
1959 }
1960 fprintf(fd, "uint64_t tsc;\n");
1961 print_tabs(1, fd);
1962 fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n");
1963 fprintf(fd, "\n");
1964
1965 print_tabs(1, fd);
ba017bc3 1966 fprintf(fd, "if(!trace) {\n");
1967 print_tabs(2, fd);
1968 fprintf(fd, "ltt_thread_init();\n");
1969 print_tabs(2, fd);
1970 fprintf(fd, "trace = thread_trace_info;\n");
1971 print_tabs(1, fd);
1972 fprintf(fd, "}\n\n");
8a9103df 1973 fprintf(fd, "\n");
1974
1975 /* Calculate event variable len + event data alignment offset.
1976 * Assume that the padding for alignment starts at a void*
1977 * address.
1978 * This excludes the header size and alignment. */
1979
1980 print_tabs(1, fd);
1981 fprintf(fd, "/* For each field, calculate the field size. */\n");
1982 print_tabs(1, fd);
1983 fprintf(fd, "/* size = *to_base + *to + *len */\n");
1984 print_tabs(1, fd);
1985 fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
1986 print_tabs(1, fd);
1987 fprintf(fd, " * sizeof(void *) address. */\n");
1988 fprintf(fd, "\n");
1989
1990 for(unsigned int i=0;i<event->fields.position;i++){
1991 field_t *field = (field_t*)(event->fields.array[i]);
1992 type_descriptor_t *type = field->type;
1993 /* Set from */
1994 print_tabs(1, fd);
1995 switch(type->type) {
1996 case SEQUENCE:
1997 case UNION:
1998 case ARRAY:
1999 case STRUCT:
2000 case STRING:
2001 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
2002 break;
2003 default:
2004 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
2005 break;
2006 }
2007
2008 if(print_type_write(type,
2009 fd, 1, basename, field->name, "lttng_param_", 0)) return 1;
2010 fprintf(fd, "\n");
2011 }
2012 print_tabs(1, fd);
2013 fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
2014
2015 print_tabs(1, fd);
2016 fprintf(fd, "trace->nesting++;\n");
2017
2018 /* Get facility index */
2019
2020 print_tabs(1, fd);
2021 fprintf(fd,
2022 "index = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
2023 "\t\t\t\t\t\tevent_%s_%s);\n",
2024 fac->name, fac->checksum, fac->name, event->name);
2025 fprintf(fd,"\n");
2026
2027
2028 print_tabs(1, fd);
2029 fprintf(fd, "{\n");
2030
2031 if(event->per_trace) {
2032 print_tabs(2, fd);
2033 fprintf(fd, "if(dest_trace != trace) continue;\n\n");
2034 }
2035
2036 print_tabs(2, fd);
2037 fprintf(fd, "ltt_buf = ltt_get_channel_from_index(trace, index);\n");
2038 print_tabs(2, fd);
2039
2040
2041 /* Relay reserve */
2042 /* If error, increment event lost counter (done by ltt_reserve_slot) and
2043 * return */
2044 print_tabs(2, fd);
2045 fprintf(fd, "slot_size = 0;\n");
2046 print_tabs(2, fd);
db6c25a6 2047 fprintf(fd, "buffer = ltt_reserve_slot(trace, ltt_buf, &transport_data,\n");
8a9103df 2048 print_tabs(3, fd);
2049 fprintf(fd, "reserve_size, &slot_size, &tsc,\n");
2050 print_tabs(3, fd);
2051 fprintf(fd, "&before_hdr_pad, &after_hdr_pad, &header_size);\n");
2052 /* If error, return */
2053 print_tabs(2, fd);
2054 fprintf(fd, "if(!buffer) goto end; /* buffer full */\n\n");
2055 //print_tabs(2, fd);
2056 // for DEBUG only
2057 // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n");
2058 print_tabs(2, fd);
2059 fprintf(fd, "*to_base = *to = *len = 0;\n");
2060 fprintf(fd, "\n");
2061
2062 /* Write event header */
2063 print_tabs(2, fd);
2064 fprintf(fd, "ltt_write_event_header(trace, ltt_buf, buffer,\n");
2065 print_tabs(3, fd);
2066 fprintf(fd, "ltt_facility_%s_%X, event_%s_%s,\n", fac->name, fac->checksum,
2067 fac->name, event->name);
2068 print_tabs(3, fd);
2069 fprintf(fd, "reserve_size, before_hdr_pad, tsc);\n");
2070 print_tabs(2, fd);
2071 fprintf(fd, "*to_base += before_hdr_pad + after_hdr_pad + header_size;\n");
2072 fprintf(fd, "\n");
2073
2074 /* write data. */
2075
2076 for(unsigned int i=0;i<event->fields.position;i++){
2077 field_t *field = (field_t*)(event->fields.array[i]);
2078 type_descriptor_t *type = field->type;
2079
2080 /* Set from */
2081 print_tabs(2, fd);
2082 switch(type->type) {
2083 case SEQUENCE:
2084 case UNION:
2085 case ARRAY:
2086 case STRUCT:
2087 case STRING:
2088 fprintf(fd, "*from = lttng_param_%s;\n", field->name);
2089 break;
2090 default:
2091 fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
2092 break;
2093 }
2094
2095
2096 if(print_type_write(type,
2097 fd, 2, basename, field->name, "lttng_param_", 0)) return 1;
2098 fprintf(fd, "\n");
2099
2100 /* Don't forget to flush pending memcpy */
2101 print_tabs(2, fd);
2102 fprintf(fd, "/* Flush pending memcpy */\n");
2103 print_tabs(2, fd);
2104 fprintf(fd, "if(*len != 0) {\n");
2105 print_tabs(3, fd);
2106 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
2107 print_tabs(3, fd);
2108 fprintf(fd, "*to += *len;\n");
2109 //print_tabs(3, fd);
2110 //fprintf(fd, "from += len;\n");
2111 print_tabs(3, fd);
2112 fprintf(fd, "*len = 0;\n");
2113 print_tabs(2, fd);
2114 fprintf(fd, "}\n");
2115 fprintf(fd, "\n");
2116 }
2117
2118
2119 /* commit */
2120 // for DEBUG only.
2121 //fprintf(fd, "commit:\n"); /* DEBUG! */
2122 print_tabs(2, fd);
db6c25a6 2123 fprintf(fd, "ltt_commit_slot(ltt_buf, &transport_data, buffer, slot_size);\n\n");
8a9103df 2124
2125 fprintf(fd, "}\n\n");
2126
2127 fprintf(fd, "end:\n");
2128 /* Release locks */
2129 print_tabs(1, fd);
2130 fprintf(fd, "trace->nesting--;\n");
2131
2132
2133 fprintf(fd, "}\n");
2134 fprintf(fd,
2135 "#endif //LTT_TRACE\n");
2136 fprintf(fd, "#endif //LTT_TRACE_FAST\n");
2137
2138 return 0;
2139}
2140
2141
2142
2143
2144
2145
2d2d14a7 2146/* ltt-facility-name.h : main logging header.
2147 * log_header */
2148
2149void print_log_header_head(facility_t *fac, FILE *fd)
2150{
2151 fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
2152 fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
3d9b9b0c 2153 fprintf(fd, "#include <linux/types.h>\n");
ffaf5031 2154 if(!fac->arch)
2155 fprintf(fd, "#include <linux/ltt/ltt-facility-id-%s.h>\n", fac->name);
2156 else
2157 fprintf(fd, "#include <asm/ltt/ltt-facility-id-%s_%s.h>\n",
2158 fac->name,
2159 fac->arch);
3d9b9b0c 2160 fprintf(fd, "#include <linux/ltt-core.h>\n");
47299663 2161 fprintf(fd, "\n");
2d2d14a7 2162}
2163
bd7b8ca6 2164/* ltt-facility-name.h : main logging header.
2165 * log_header */
2166
2167void print_log_header_head_user(facility_t *fac, FILE *fd)
2168{
2169 fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
2170 fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
2171 fprintf(fd, "#include <sys/types.h>\n");
2172 if(!fac->arch)
2173 fprintf(fd, "#include <ltt/ltt-facility-id-%s.h>\n", fac->name);
2174 else
2175 fprintf(fd, "#include <asm/ltt/ltt-facility-id-%s_%s.h>\n",
2176 fac->name,
2177 fac->arch);
f389e596 2178 fprintf(fd, "#include <ltt/ltt-usertrace.h>\n");
bd7b8ca6 2179 fprintf(fd, "\n");
2180}
2d2d14a7 2181
2182
2d2d14a7 2183int print_log_header_types(facility_t *fac, FILE *fd)
2184{
2185 sequence_t *types = &fac->named_types.values;
2186 fprintf(fd, "/* Named types */\n");
2187 fprintf(fd, "\n");
2188
2189 for(unsigned int i = 0; i < types->position; i++) {
2190 /* For each named type, print the definition */
458989d8 2191 if(print_type_declaration(types->array[i], fd,
2192 0, "", "")) return 1;
34c1d1b5 2193 /* Print also the align function */
458989d8 2194 if(print_type_alignment_fct(types->array[i], fd,
2195 0, "", "")) return 1;
34c1d1b5 2196 /* Print also the write function */
458989d8 2197 if(print_type_write_fct(types->array[i], fd,
2198 0, "", "")) return 1;
2d2d14a7 2199 }
2200 return 0;
2201}
2202
2203int print_log_header_events(facility_t *fac, FILE *fd)
2204{
47299663 2205 sequence_t *events = &fac->events;
2206 char basename[PATH_MAX];
2207 unsigned int facname_len;
2208
2209 strncpy(basename, fac->name, PATH_MAX);
2210 facname_len = strlen(basename);
2211 strncat(basename, "_", PATH_MAX-facname_len);
2212 facname_len = strlen(basename);
2213
2214 for(unsigned int i = 0; i < events->position; i++) {
2215 event_t *event = (event_t*)events->array[i];
2216 strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
2217
2218 /* For each event, print structure, and then logging function */
2219 fprintf(fd, "/* Event %s structures */\n",
2220 event->name);
2221 for(unsigned int j = 0; j < event->fields.position; j++) {
2222 /* For each unnamed type, print the definition */
2223 field_t *f = (field_t*)event->fields.array[j];
2224 type_descriptor_t *t = f->type;
34c1d1b5 2225 if(t->type_name == NULL) {
47299663 2226 if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
34c1d1b5 2227 /* Print also the align function */
2228 if((print_type_alignment_fct(t, fd, 0, basename, f->name))) return 1;
2229 /* Print also the write function */
2230 if((print_type_write_fct(t, fd, 0, basename, f->name))) return 1;
2231 }
47299663 2232 }
34c1d1b5 2233
47299663 2234 fprintf(fd, "\n");
2d2d14a7 2235
47299663 2236 fprintf(fd, "/* Event %s logging function */\n",
2237 event->name);
bd7b8ca6 2238
2239 if(!fac->user) {
2240 if(print_event_logging_function(basename, fac, event, fd)) return 1;
2241 } else {
8a9103df 2242 if(print_event_logging_function_user_generic(basename, fac, event, fd))
2243 return 1;
2244 if(print_event_logging_function_user_fast(basename, fac, event, fd))
2245 return 1;
bd7b8ca6 2246 }
47299663 2247
2248 fprintf(fd, "\n");
2249 }
2250
2d2d14a7 2251 return 0;
2252}
2253
2254
2255void print_log_header_tail(facility_t *fac, FILE *fd)
2256{
2257 fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
2258}
bd7b8ca6 2259
2260void print_log_header_tail_user(facility_t *fac, FILE *fd)
2261{
2262 fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
2263}
2d2d14a7 2264
2265int print_log_header(facility_t *fac)
2266{
2267 char filename[PATH_MAX];
2268 unsigned int filename_size = 0;
2269 FILE *fd;
2270 dprintf("%s\n", fac->name);
2271
2272 strcpy(filename, "ltt-facility-");
2273 filename_size = strlen(filename);
2274
2275 strncat(filename, fac->name, PATH_MAX - filename_size);
2276 filename_size = strlen(filename);
2277
ffaf5031 2278 if(fac->arch) {
2279 strncat(filename, "_", PATH_MAX - filename_size);
2280 filename_size = strlen(filename);
2281
2282 strncat(filename, fac->arch, PATH_MAX - filename_size);
2283 filename_size = strlen(filename);
2284 }
2285
2d2d14a7 2286 strncat(filename, ".h", PATH_MAX - filename_size);
2287 filename_size = strlen(filename);
2288
2289
2290 fd = fopen(filename, "w");
2291 if(fd == NULL) {
2292 printf("Error opening file %s for writing : %s\n",
2293 filename, strerror(errno));
2294 return errno;
2295 }
2296
2297 /* Print file head */
bd7b8ca6 2298 if(!fac->user)
2299 print_log_header_head(fac, fd);
2300 else
2301 print_log_header_head_user(fac, fd);
2d2d14a7 2302
2303 /* print named types in declaration order */
2304 if(print_log_header_types(fac, fd)) return 1;
2305
2306 /* Print events */
2307 if(print_log_header_events(fac, fd)) return 1;
2308
2309 /* Print file tail */
bd7b8ca6 2310 if(!fac->user)
2311 print_log_header_tail(fac, fd);
2312 else
2313 print_log_header_tail_user(fac, fd);
2314
2d2d14a7 2315
2316
2317 fclose(fd);
2318
2319 return 0;
2320}
2321
2322
2323/* ltt-facility-id-name.h : facility id.
2324 * log_id_header */
2325int print_id_header(facility_t *fac)
2326{
2327 char filename[PATH_MAX];
2328 unsigned int filename_size = 0;
2329 FILE *fd;
71e09db9 2330 char basename[PATH_MAX];
2331 char basename_len = 0;
2332
2d2d14a7 2333 dprintf("%s\n", fac->name);
2334
2335 strcpy(filename, "ltt-facility-id-");
2336 filename_size = strlen(filename);
2337
2338 strncat(filename, fac->name, PATH_MAX - filename_size);
2339 filename_size = strlen(filename);
2340
ffaf5031 2341 if(fac->arch) {
2342 strncat(filename, "_", PATH_MAX - filename_size);
2343 filename_size = strlen(filename);
2344
2345 strncat(filename, fac->arch, PATH_MAX - filename_size);
2346 filename_size = strlen(filename);
2347 }
2348
2d2d14a7 2349 strncat(filename, ".h", PATH_MAX - filename_size);
2350 filename_size = strlen(filename);
2351
2352
2353 fd = fopen(filename, "w");
2354 if(fd == NULL) {
2355 printf("Error opening file %s for writing : %s\n",
2356 filename, strerror(errno));
2357 return errno;
2358 }
2359
bd7b8ca6 2360 if(!fac->user) {
2361 fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
2362 fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
2363 fprintf(fd, "#ifdef CONFIG_LTT\n");
71e09db9 2364
bd7b8ca6 2365 fprintf(fd,"#include <linux/ltt-facilities.h>\n\n");
71e09db9 2366
bd7b8ca6 2367 fprintf(fd,"/**** facility handle ****/\n\n");
2368 fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
2369 fac->name, fac->checksum);
2370 fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
71e09db9 2371
bd7b8ca6 2372 strncpy(basename, fac->name, PATH_MAX);
2373 basename_len = strlen(basename);
2374 strncat(basename, "_", PATH_MAX - basename_len);
2375 basename_len++;
2376
2377 fprintf(fd,"/**** event index ****/\n\n");
2378 fprintf(fd,"enum %s_event {\n",fac->name);
2379
2380 for(unsigned int i = 0; i < fac->events.position; i++) {
2381 event_t *event = (event_t*)fac->events.array[i];
2382 strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
2383 print_tabs(1, fd);
2384 fprintf(fd, "event_%s,\n", basename);
2385 }
71e09db9 2386 print_tabs(1, fd);
bd7b8ca6 2387 fprintf(fd, "facility_%s_num_events\n", fac->name);
2388 fprintf(fd, "};\n");
2389 fprintf(fd, "\n");
71e09db9 2390
2391
bd7b8ca6 2392 fprintf(fd, "#endif //CONFIG_LTT\n");
2393 fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
2394 } else {
2395 fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
2396 fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
2397 fprintf(fd, "#ifdef LTT_TRACE\n");
2398
f389e596 2399 fprintf(fd,"#include <ltt/ltt-usertrace.h>\n\n");
bd7b8ca6 2400
2401 fprintf(fd,"/**** facility handle ****/\n\n");
2402 fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
2403 fac->name, fac->checksum);
2404 fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
2405
2406 strncpy(basename, fac->name, PATH_MAX);
2407 basename_len = strlen(basename);
2408 strncat(basename, "_", PATH_MAX - basename_len);
2409 basename_len++;
2410
2411 fprintf(fd,"/**** event index ****/\n\n");
2412 fprintf(fd,"enum %s_event {\n",fac->name);
2413
2414 for(unsigned int i = 0; i < fac->events.position; i++) {
2415 event_t *event = (event_t*)fac->events.array[i];
2416 strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
2417 print_tabs(1, fd);
2418 fprintf(fd, "event_%s,\n", basename);
2419 }
2420 print_tabs(1, fd);
2421 fprintf(fd, "facility_%s_num_events\n", fac->name);
2422 fprintf(fd, "};\n");
2423 fprintf(fd, "\n");
2424
2425
2426 fprintf(fd, "#endif //LTT_TRACE\n");
2427 fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
2428 }
71e09db9 2429
2430
2d2d14a7 2431 fclose(fd);
2432
2433 return 0;
2434}
2435
2436
2437/* ltt-facility-loader-name.h : facility specific loader info.
2438 * loader_header */
2439int print_loader_header(facility_t *fac)
2440{
2441 char filename[PATH_MAX];
2442 unsigned int filename_size = 0;
2443 FILE *fd;
2444 dprintf("%s\n", fac->name);
2445
2446 strcpy(filename, "ltt-facility-loader-");
2447 filename_size = strlen(filename);
2448
2449 strncat(filename, fac->name, PATH_MAX - filename_size);
2450 filename_size = strlen(filename);
2451
ffaf5031 2452 if(fac->arch) {
2453 strncat(filename, "_", PATH_MAX - filename_size);
2454 filename_size = strlen(filename);
2455
2456 strncat(filename, fac->arch, PATH_MAX - filename_size);
2457 filename_size = strlen(filename);
2458 }
2459
2d2d14a7 2460 strncat(filename, ".h", PATH_MAX - filename_size);
2461 filename_size = strlen(filename);
2462
2463
2464 fd = fopen(filename, "w");
2465 if(fd == NULL) {
2466 printf("Error opening file %s for writing : %s\n",
2467 filename, strerror(errno));
2468 return errno;
2469 }
2470
71e09db9 2471 fprintf(fd, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
2472 fprintf(fd, "#define _LTT_FACILITY_LOADER_%s_H_\n\n", fac->capname);
2473 fprintf(fd, "#ifdef CONFIG_LTT\n\n");
2474 fprintf(fd,"#include <linux/ltt-facilities.h>\n");
ffaf5031 2475 if(!fac->arch)
2476 fprintf(fd,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n",
2477 fac->name);
2478 else
2479 fprintf(fd,"#include <asm/ltt/ltt-facility-id-%s_%s.h>\n\n",
2480 fac->name,
2481 fac->arch);
71e09db9 2482 fprintf(fd,"ltt_facility_t\tltt_facility_%s;\n", fac->name);
2483 fprintf(fd,"ltt_facility_t\tltt_facility_%s_%X;\n\n",
2484 fac->name, fac->checksum);
2485
0043cb00 2486 fprintf(fd,"#define LTT_FACILITY_SYMBOL\t\tltt_facility_%s\n",
71e09db9 2487 fac->name);
0043cb00 2488 fprintf(fd,"#define LTT_FACILITY_CHECKSUM_SYMBOL\tltt_facility_%s_%X\n",
71e09db9 2489 fac->name, fac->checksum);
0043cb00 2490 fprintf(fd,"#define LTT_FACILITY_CHECKSUM\t\t0x%X\n", fac->checksum);
2491 fprintf(fd,"#define LTT_FACILITY_NAME\t\t\"%s\"\n", fac->name);
2492 fprintf(fd,"#define LTT_FACILITY_NUM_EVENTS\tfacility_%s_num_events\n\n",
71e09db9 2493 fac->name);
2494 fprintf(fd, "#endif //CONFIG_LTT\n\n");
2495 fprintf(fd, "#endif //_LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
2496
2d2d14a7 2497 fclose(fd);
2498
2499 return 0;
2500}
2501
bd7b8ca6 2502int print_loader_header_user(facility_t *fac)
2503{
2504 char filename[PATH_MAX];
2505 unsigned int filename_size = 0;
2506 FILE *fd;
2507 dprintf("%s\n", fac->name);
2508
2509 strcpy(filename, "ltt-facility-loader-");
2510 filename_size = strlen(filename);
2511
2512 strncat(filename, fac->name, PATH_MAX - filename_size);
2513 filename_size = strlen(filename);
2514
2515 if(fac->arch) {
2516 strncat(filename, "_", PATH_MAX - filename_size);
2517 filename_size = strlen(filename);
2518
2519 strncat(filename, fac->arch, PATH_MAX - filename_size);
2520 filename_size = strlen(filename);
2521 }
2522
2523 strncat(filename, ".h", PATH_MAX - filename_size);
2524 filename_size = strlen(filename);
2525
2526
2527 fd = fopen(filename, "w");
2528 if(fd == NULL) {
2529 printf("Error opening file %s for writing : %s\n",
2530 filename, strerror(errno));
2531 return errno;
2532 }
2533
2534 fprintf(fd, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
2535 fprintf(fd, "#define _LTT_FACILITY_LOADER_%s_H_\n\n", fac->capname);
f389e596 2536 fprintf(fd,"#include <ltt/ltt-usertrace.h>\n");
bd7b8ca6 2537 if(!fac->arch)
2538 fprintf(fd,"#include <ltt/ltt-facility-id-%s.h>\n\n",
2539 fac->name);
2540 else
2541 fprintf(fd,"#include <asm/ltt/ltt-facility-id-%s_%s.h>\n\n",
2542 fac->name,
2543 fac->arch);
2544 fprintf(fd,"ltt_facility_t\tltt_facility_%s;\n", fac->name);
2545 fprintf(fd,"ltt_facility_t\tltt_facility_%s_%X;\n\n",
2546 fac->name, fac->checksum);
2547
2548 fprintf(fd,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
2549 fac->name);
2550 fprintf(fd,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
2551 fac->name, fac->checksum);
2552 fprintf(fd,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", fac->checksum);
2553 fprintf(fd,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", fac->name);
2554 fprintf(fd,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\tfacility_%s_num_events\n\n",
2555 fac->name);
2556 fprintf(fd, "#endif //_LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
2557
2558 fclose(fd);
2559
2560 return 0;
2561}
2562
2563
2564
2565/* ltt-facility-loader-name.c : generic facility loader
2d2d14a7 2566 * loader_c */
2567int print_loader_c(facility_t *fac)
2568{
2569 char filename[PATH_MAX];
2570 unsigned int filename_size = 0;
2571 FILE *fd;
2572 dprintf("%s\n", fac->name);
2573
2574 strcpy(filename, "ltt-facility-loader-");
2575 filename_size = strlen(filename);
2576
2577 strncat(filename, fac->name, PATH_MAX - filename_size);
2578 filename_size = strlen(filename);
2579
ffaf5031 2580 if(fac->arch) {
2581 strncat(filename, "_", PATH_MAX - filename_size);
2582 filename_size = strlen(filename);
2583
2584 strncat(filename, fac->arch, PATH_MAX - filename_size);
2585 filename_size = strlen(filename);
2586 }
2587
2d2d14a7 2588 strncat(filename, ".c", PATH_MAX - filename_size);
2589 filename_size = strlen(filename);
2590
2591
2592 fd = fopen(filename, "w");
2593 if(fd == NULL) {
2594 printf("Error opening file %s for writing : %s\n",
2595 filename, strerror(errno));
2596 return errno;
2597 }
2598
71e09db9 2599 fprintf(fd, "/*\n");
ffaf5031 2600 if(!fac->arch)
2601 fprintf(fd, " * ltt-facility-loader-%s.c\n", fac->name);
2602 else
2603 fprintf(fd, " * ltt-facility-loader-%s_%s.c\n", fac->name, fac->arch);
71e09db9 2604 fprintf(fd, " *\n");
2605 fprintf(fd, " * (C) Copyright 2005 - \n");
2606 fprintf(fd, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
2607 fprintf(fd, " *\n");
2608 fprintf(fd, " * Contains the LTT facility loader.\n");
2609 fprintf(fd, " *\n");
2610 fprintf(fd, " */\n");
2611 fprintf(fd, "\n");
2612 fprintf(fd, "\n");
2613 fprintf(fd, "#include <linux/ltt-facilities.h>\n");
2614 fprintf(fd, "#include <linux/module.h>\n");
2615 fprintf(fd, "#include <linux/init.h>\n");
2616 fprintf(fd, "#include <linux/config.h>\n");
ffaf5031 2617 if(!fac->arch)
2618 fprintf(fd, "#include \"ltt-facility-loader-%s.h\"\n", fac->name);
2619 else
2620 fprintf(fd, "#include \"ltt-facility-loader-%s_%s.h\"\n",
2621 fac->name, fac->arch);
71e09db9 2622 fprintf(fd, "\n");
2623 fprintf(fd, "\n");
2624 fprintf(fd, "#ifdef CONFIG_LTT\n");
2625 fprintf(fd, "\n");
2626 fprintf(fd, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
2627 fprintf(fd, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
2628 fprintf(fd, "\n");
2629 fprintf(fd, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
2630 fprintf(fd, "\n");
2631 fprintf(fd, "#define SYMBOL_STRING(sym) #sym\n");
2632 fprintf(fd, "\n");
2633 fprintf(fd, "static struct ltt_facility facility = {\n");
2634 fprintf(fd, "\t.name = ltt_facility_name,\n");
2635 fprintf(fd, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
2636 fprintf(fd, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
2637 fprintf(fd, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
2638 fprintf(fd, "};\n");
2639 fprintf(fd, "\n");
71e09db9 2640 fprintf(fd, "static int __init facility_init(void)\n");
2641 fprintf(fd, "{\n");
2642 fprintf(fd, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", fac->name);
2643 fprintf(fd, "\n");
bd7b8ca6 2644 fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_kernel_register(&facility);\n");
71e09db9 2645 fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
2646 fprintf(fd, "\t\n");
2647 fprintf(fd, "\treturn LTT_FACILITY_SYMBOL;\n");
2648 fprintf(fd, "}\n");
71e09db9 2649 fprintf(fd, "\n");
bd7b8ca6 2650 fprintf(fd, "#ifndef MODULE\n");
ba899d3d 2651 fprintf(fd, "__initcall(facility_init);\n");
2652 fprintf(fd, "#else\n");
2653 fprintf(fd, "module_init(facility_init);\n");
71e09db9 2654 fprintf(fd, "static void __exit facility_exit(void)\n");
2655 fprintf(fd, "{\n");
2656 fprintf(fd, "\tint err;\n");
2657 fprintf(fd, "\n");
bd7b8ca6 2658 fprintf(fd, "\terr = ltt_facility_unregister(LTT_FACILITY_SYMBOL);\n");
71e09db9 2659 fprintf(fd, "\tif(err != 0)\n");
2660 fprintf(fd, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
2661 fprintf(fd, "\n");
2662 fprintf(fd, "}\n");
71e09db9 2663 fprintf(fd, "module_exit(facility_exit)\n");
2664 fprintf(fd, "\n");
71e09db9 2665 fprintf(fd, "MODULE_LICENSE(\"GPL\");\n");
2666 fprintf(fd, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
2667 fprintf(fd, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
2668 fprintf(fd, "\n");
2669 fprintf(fd, "#endif //MODULE\n");
2670 fprintf(fd, "\n");
2671 fprintf(fd, "#endif //CONFIG_LTT\n");
2d2d14a7 2672
2673 fclose(fd);
2674
2675 return 0;
2676}
2677
bd7b8ca6 2678int print_loader_c_user(facility_t *fac)
2679{
2680 char filename[PATH_MAX];
2681 unsigned int filename_size = 0;
2682 FILE *fd;
2683 dprintf("%s\n", fac->name);
2684
2685 strcpy(filename, "ltt-facility-loader-");
2686 filename_size = strlen(filename);
2687
2688 strncat(filename, fac->name, PATH_MAX - filename_size);
2689 filename_size = strlen(filename);
2690
2691 if(fac->arch) {
2692 strncat(filename, "_", PATH_MAX - filename_size);
2693 filename_size = strlen(filename);
2694
2695 strncat(filename, fac->arch, PATH_MAX - filename_size);
2696 filename_size = strlen(filename);
2697 }
2698
2699 strncat(filename, ".c", PATH_MAX - filename_size);
2700 filename_size = strlen(filename);
2701
2702
2703 fd = fopen(filename, "w");
2704 if(fd == NULL) {
2705 printf("Error opening file %s for writing : %s\n",
2706 filename, strerror(errno));
2707 return errno;
2708 }
2709
2710 fprintf(fd, "/*\n");
2711 if(!fac->arch)
2712 fprintf(fd, " * ltt-facility-loader-%s.c\n", fac->name);
2713 else
2714 fprintf(fd, " * ltt-facility-loader-%s_%s.c\n", fac->name, fac->arch);
2715 fprintf(fd, " *\n");
2716 fprintf(fd, " * (C) Copyright 2005 - \n");
2717 fprintf(fd, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
2718 fprintf(fd, " *\n");
2719 fprintf(fd, " * Contains the LTT user space facility loader.\n");
2720 fprintf(fd, " *\n");
2721 fprintf(fd, " */\n");
2722 fprintf(fd, "\n");
2723 fprintf(fd, "\n");
2724 fprintf(fd, "#define LTT_TRACE\n");
2725 fprintf(fd, "#include <error.h>\n");
2726 fprintf(fd, "#include <stdio.h>\n");
f389e596 2727 fprintf(fd, "#include <ltt/ltt-usertrace.h>\n");
bd7b8ca6 2728 if(!fac->arch)
2729 fprintf(fd, "#include \"ltt-facility-loader-%s.h\"\n", fac->name);
2730 else
2731 fprintf(fd, "#include \"ltt-facility-loader-%s_%s.h\"\n",
2732 fac->name, fac->arch);
2733 fprintf(fd, "\n");
2734 fprintf(fd, "static struct user_facility_info facility = {\n");
2735 fprintf(fd, "\t.name = LTT_FACILITY_NAME,\n");
2736 fprintf(fd, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
2737 fprintf(fd, "#ifndef LTT_PACK\n");
2738 fprintf(fd, "\t.alignment = sizeof(void*),\n");
2739 fprintf(fd, "#else\n");
2740 fprintf(fd, "\t.alignment = 0,\n");
2741 fprintf(fd, "#endif //LTT_PACK\n");
2742 fprintf(fd, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
2743 fprintf(fd, "\t.int_size = sizeof(int),\n");
2744 fprintf(fd, "\t.long_size = sizeof(long),\n");
2745 fprintf(fd, "\t.pointer_size = sizeof(void*),\n");
2746 fprintf(fd, "\t.size_t_size = sizeof(size_t)\n");
2747 fprintf(fd, "};\n");
2748 fprintf(fd, "\n");
2749 fprintf(fd, "static void __attribute__((constructor)) __ltt_user_init(void)\n");
2750 fprintf(fd, "{\n");
2751 fprintf(fd, "\tint err;\n");
2d6c6b76 2752 fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n");
bd7b8ca6 2753 fprintf(fd, "\tprintf(\"LTT : ltt-facility-%s init in userspace\\n\");\n", fac->name);
2d6c6b76 2754 fprintf(fd, "#endif //LTT_SHOW_DEBUG\n");
bd7b8ca6 2755 fprintf(fd, "\n");
2756 fprintf(fd, "\terr = ltt_register_generic(&LTT_FACILITY_SYMBOL, &facility);\n");
2757 fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
2758 fprintf(fd, "\t\n");
2759 fprintf(fd, "\tif(err) {\n");
2d6c6b76 2760 fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n");
bd7b8ca6 2761 fprintf(fd, "\t\tperror(\"Error in ltt_register_generic\");\n");
2d6c6b76 2762 fprintf(fd, "#endif //LTT_SHOW_DEBUG\n");
bd7b8ca6 2763 fprintf(fd, "\t}\n");
2764 fprintf(fd, "}\n");
2765 fprintf(fd, "\n");
2766
2767 fclose(fd);
2768
2769 return 0;
2770}
2771
2d2d14a7 2772
2773
92d82357 2774/* open facility */
2775/* code taken from ltt_facility_open in ltt/facility.c in lttv */
2776
2777/*****************************************************************************
2778 *Function name
2779 * ltt_facility_open : open facilities
2780 *Input params
2781 * pathname : the path name of the facility
2782 *
2783 * Open the facility corresponding to the right checksum.
2784 *
2785 *returns the facility on success, NULL on error.
2786 ****************************************************************************/
2787facility_t *ltt_facility_open(char * pathname)
2788{
2789 int ret = 0;
2790 char *token;
2791 parse_file_t in;
2792 facility_t * fac = NULL;
92d82357 2793 char buffer[BUFFER_SIZE];
2794 int generated = FALSE;
2795
2796 in.buffer = &(buffer[0]);
2797 in.lineno = 0;
2798 in.error = error_callback;
2799 in.name = pathname;
2800 in.unget = 0;
2801
2802 in.fp = fopen(in.name, "r");
2803 if(in.fp == NULL) {
2804 ret = 1;
2805 goto open_error;
2806 }
2807
2808 while(1){
2809 token = getToken(&in);
2810 if(in.type == ENDFILE) break;
2811
2812 if(generated) {
2813 printf("More than one facility in the file. Only using the first one.\n");
2814 break;
2815 }
2816
2817 if(strcmp(token, "<")) in.error(&in,"not a facility file");
2818 token = getName(&in);
f389e596 2819 if(strcmp(token, "?")) in.error(&in,"not a facility file");
2820 token = getName(&in);
2821 if(strcmp(token, "xml")) in.error(&in,"not a facility file");
2822 token = getName(&in);
2823 if(strcmp(token, "version")) in.error(&in,"not a facility file");
2824 token = getName(&in);
2825 if(strcmp(token, "=")) in.error(&in,"not a facility file");
2826 token = getQuotedString(&in);
2827 if(strcmp(token, "1.0")) in.error(&in,"not a facility file");
2828 token = getName(&in);
2829 if(strcmp(token, "?")) in.error(&in,"not a facility file");
2830 token = getToken(&in);
2831 if(strcmp(token, ">")) in.error(&in,"not a facility file");
92d82357 2832
f389e596 2833 token = getName(&in);
2834 if(strcmp(token, "<")) in.error(&in,"not a facility file");
2835 token = getName(&in);
92d82357 2836 if(strcmp("facility",token) == 0) {
2837 fac = malloc(sizeof(facility_t));
2838 fac->name = NULL;
2839 fac->description = NULL;
2840 sequence_init(&(fac->events));
2841 table_init(&(fac->named_types));
2842 sequence_init(&(fac->unnamed_types));
2843
2844 parseFacility(&in, fac);
2845
2846 //check if any namedType is not defined
2847 checkNamedTypesImplemented(&fac->named_types);
2848
2e415130 2849 generateChecksum(fac->name, &fac->checksum, &fac->events);
a67cd958 2850
92d82357 2851 generated = TRUE;
2852 }
2853 else {
2854 printf("facility token was expected in file %s\n", in.name);
2855 ret = 1;
2856 goto parse_error;
2857 }
2858 }
2859
2860 parse_error:
2861 fclose(in.fp);
2862open_error:
2863
2864 if(!generated) {
2865 printf("Cannot find facility %s\n", pathname);
2866 fac = NULL;
2867 }
2868
2869 return fac;
2870}
2871
2872/* Close the facility */
2873void ltt_facility_close(facility_t *fac)
2874{
2875 free(fac->name);
2876 free(fac->capname);
2877 free(fac->description);
2878 freeEvents(&fac->events);
2879 sequence_dispose(&fac->events);
2880 freeNamedType(&fac->named_types);
2881 table_dispose(&fac->named_types);
2882 freeTypes(&fac->unnamed_types);
2883 sequence_dispose(&fac->unnamed_types);
2884 free(fac);
2885}
2886
2887
2888/* Show help */
2889void show_help(int argc, char ** argv)
2890{
2891 printf("Genevent help : \n");
2892 printf("\n");
2893 printf("Use %s name.xml\n", argv[0]);
2894 printf("to create :\n");
2895 printf("ltt-facility-name.h\n");
2896 printf("ltt-facility-id-name.h\n");
2897 printf("ltt-facility-loader-name.h\n");
2898 printf("ltt-facility-loader-name.c\n");
2899 printf("In the current directory.\n");
2900 printf("\n");
2901}
2902
2903/* Parse program arguments */
2904/* Return values :
2905 * 0 : continue program
2906 * -1 : stop program, return 0
2907 * > 0 : stop program, return value as exit.
2908 */
2909int check_args(int argc, char **argv)
2910{
2911 if(argc < 2) {
2912 printf("Not enough arguments\n");
2913 show_help(argc, argv);
2914 return EINVAL;
2915 }
2916
2917 if(strcmp(argv[1], "-h") == 0) {
2918 show_help(argc, argv);
2919 return -1;
2920 }
2921
2922 return 0;
2923}
2924
2925int main(int argc, char **argv)
2926{
2927 int err = 0;
2928 facility_t *fac;
2929
2930 err = check_args(argc, argv);
2931 if(err > 0) return err;
2932 else if(err < 0) return 0;
2933
2934 /* open the facility */
2935 fac = ltt_facility_open(argv[1]);
2936 if(fac == NULL) {
2937 printf("Error opening file %s for reading : %s\n",
2938 argv[1], strerror(errno));
2939 return errno;
2940 }
2941
2942 /* generate the output C files */
2943
2944
2d2d14a7 2945 /* ltt-facility-name.h : main logging header.
2946 * log_header */
2947 err = print_log_header(fac);
2948 if(err) return err;
92d82357 2949
2d2d14a7 2950 /* ltt-facility-id-name.h : facility id.
2951 * log_id_header */
2952 err = print_id_header(fac);
2953 if(err) return err;
92d82357 2954
2d2d14a7 2955 /* ltt-facility-loader-name.h : facility specific loader info.
2956 * loader_header */
bd7b8ca6 2957 if(!fac->user)
2958 err = print_loader_header(fac);
2959 else
2960 err = print_loader_header_user(fac);
2d2d14a7 2961 if(err) return err;
2962
2963 /* ltt-facility-loader-name.c : generic faciilty loader
2964 * loader_c */
bd7b8ca6 2965 if(!fac->user)
2966 err = print_loader_c(fac);
2967 else
2968 err = print_loader_c_user(fac);
2d2d14a7 2969 if(err) return err;
92d82357 2970
2971 /* close the facility */
2972 ltt_facility_close(fac);
2973
2974 return 0;
2975}
2976
2977
This page took 0.161274 seconds and 4 git commands to generate.