genevent compile fix for generated code
[lttv.git] / genevent-new / genevent.c
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
58 #define _GNU_SOURCE
59 #include <limits.h>
60 #include <stdlib.h>
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>
68 #include <assert.h>
69
70 #include "genevent.h"
71 #include "parser.h"
72
73
74 #define TRUE 1
75 #define FALSE (!TRUE)
76
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
89 /* Code printing */
90
91 void print_tabs(unsigned int tabs, FILE *fd)
92 {
93 for(unsigned int i = 0; i<tabs;i++)
94 fprintf(fd, "\t");
95 }
96
97 /* print type.
98 *
99 * Copied from construct_types_and_fields in LTTV facility.c */
100
101 int 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 */
116 if((basename_len != 0)
117 && (basename[basename_len-1] != '_')
118 && (field_name[0] != '\0')) {
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:
154 fprintf(fd, "const void *");
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:
172 fprintf(fd, "const char *");
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
197 /* Print logging function argument */
198 int 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)]);
227 fprintf(fd, " %s", field_name);
228 break;
229 case UINT_FIXED:
230 fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]);
231 fprintf(fd, " %s", field_name);
232 break;
233 case CHAR:
234 fprintf(fd, "signed char");
235 fprintf(fd, " %s", field_name);
236 break;
237 case UCHAR:
238 fprintf(fd, "unsigned char");
239 fprintf(fd, " %s", field_name);
240 break;
241 case SHORT:
242 fprintf(fd, "short");
243 fprintf(fd, " %s", field_name);
244 break;
245 case USHORT:
246 fprintf(fd, "unsigned short");
247 fprintf(fd, " %s", field_name);
248 break;
249 case INT:
250 fprintf(fd, "int");
251 fprintf(fd, " %s", field_name);
252 break;
253 case UINT:
254 fprintf(fd, "unsigned int");
255 fprintf(fd, " %s", field_name);
256 break;
257 case FLOAT:
258 fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]);
259 fprintf(fd, " %s", field_name);
260 break;
261 case POINTER:
262 fprintf(fd, "const void *");
263 fprintf(fd, " %s", field_name);
264 break;
265 case LONG:
266 fprintf(fd, "long");
267 fprintf(fd, " %s", field_name);
268 break;
269 case ULONG:
270 fprintf(fd, "unsigned long");
271 fprintf(fd, " %s", field_name);
272 break;
273 case SIZE_T:
274 fprintf(fd, "size_t");
275 fprintf(fd, " %s", field_name);
276 break;
277 case SSIZE_T:
278 fprintf(fd, "ssize_t");
279 fprintf(fd, " %s", field_name);
280 break;
281 case OFF_T:
282 fprintf(fd, "off_t");
283 fprintf(fd, " %s", field_name);
284 break;
285 case STRING:
286 fprintf(fd, "const char *");
287 fprintf(fd, " %s", field_name);
288 break;
289 case ENUM:
290 fprintf(fd, "enum lttng_%s", basename);
291 fprintf(fd, " %s", field_name);
292 break;
293 case ARRAY:
294 fprintf(fd, "lttng_array_%s", basename);
295 fprintf(fd, " %s", field_name);
296 break;
297 case SEQUENCE:
298 fprintf(fd, "lttng_sequence_%s *", basename);
299 fprintf(fd, " %s", field_name);
300 break;
301 case STRUCT:
302 fprintf(fd, "struct lttng_%s *", basename);
303 fprintf(fd, " %s", field_name);
304 break;
305 case UNION:
306 fprintf(fd, "union lttng_%s *", basename);
307 fprintf(fd, " %s", field_name);
308 break;
309 default:
310 printf("print_type : unknown type\n");
311 return 1;
312 }
313
314 return 0;
315 }
316
317
318 /* Does the type has a fixed size ? (as know from the compiler)
319 *
320 * 1 : fixed size
321 * 0 : variable length
322 */
323 int 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);
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);
370 break;
371 }
372 return 0; //make gcc happy.
373 }
374
375
376
377
378
379 /* print type declaration.
380 *
381 * Copied from construct_types_and_fields in LTTV facility.c */
382
383 int 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
389 strncpy(basename, nest_name, PATH_MAX);
390 basename_len = strlen(basename);
391
392 /* For a named type, we use the type_name directly */
393 if(td->type_name != NULL) {
394 strncpy(basename, td->type_name, PATH_MAX);
395 basename_len = strlen(basename);
396 } else {
397 /* For a unnamed type, there must be a field name, except for
398 * the array. */
399 if((basename_len != 0)
400 && (basename[basename_len-1] != '_'
401 && (field_name[0] != '\0'))) {
402 strncat(basename, "_", PATH_MAX - basename_len);
403 basename_len = strlen(basename);
404 }
405 strncat(basename, field_name, PATH_MAX - basename_len);
406 }
407
408 switch(td->type) {
409 case ENUM:
410 fprintf(fd, "enum lttng_%s", basename);
411 fprintf(fd, " {\n");
412 for(unsigned int i=0;i<td->labels.position;i++){
413 print_tabs(1, fd);
414 fprintf(fd, "LTTNG_%s", ((char*)(td->labels.array[i])));
415 fprintf(fd, ",\n");
416 }
417 fprintf(fd, "};\n");
418 fprintf(fd, "\n");
419 break;
420
421 case ARRAY:
422 dprintf("%s\n", basename);
423 assert(td->size >= 0);
424 if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
425 /* Not a named nested type : we must print its declaration first */
426 if(print_type_declaration(((field_t*)td->fields.array[0])->type,
427 fd, 0, basename, "")) return 1;
428 }
429 fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %zu\n", basename,
430 td->size);
431 fprintf(fd, "typedef ");
432 if(print_type(((field_t*)td->fields.array[0])->type,
433 fd, tabs, basename, "")) return 1;
434 fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename,
435 basename);
436 fprintf(fd, "\n");
437 break;
438 case SEQUENCE:
439 /* We assume that the sequence length type does not need to be declared.
440 */
441 if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
442 /* Not a named nested type : we must print its declaration first */
443 if(print_type_declaration(((field_t*)td->fields.array[1])->type,
444 fd, 0, basename, "")) return 1;
445 }
446 fprintf(fd, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n",
447 basename,
448 basename);
449 fprintf(fd, "struct lttng_sequence_%s", basename);
450 fprintf(fd, " {\n");
451 print_tabs(1, fd);
452 if(print_type(((field_t*)td->fields.array[0])->type,
453 fd, tabs, basename, "")) return 1;
454 fprintf(fd, " len;\n");
455 print_tabs(1, fd);
456 fprintf(fd, "const ");
457 if(print_type(((field_t*)td->fields.array[1])->type,
458 fd, tabs, basename, "")) return 1;
459 fprintf(fd, " *array;\n");
460 fprintf(fd, "};\n"); /* We do not LTT_ALIGN, because we never copy
461 it to the buffer directly. */
462 fprintf(fd, "\n");
463 break;
464
465 case STRUCT:
466 for(unsigned int i=0;i<td->fields.position;i++){
467 field_t *field = (field_t*)(td->fields.array[i]);
468 type_descriptor_t *type = field->type;
469 if(type->type_name == NULL) {
470 /* Not a named nested type : we must print its declaration first */
471 if(print_type_declaration(type,
472 fd, 0, basename, field->name)) return 1;
473 }
474 }
475 fprintf(fd, "struct lttng_%s", basename);
476 fprintf(fd, " {\n");
477 for(unsigned int i=0;i<td->fields.position;i++){
478 field_t *field = (field_t*)(td->fields.array[i]);
479 type_descriptor_t *type = field->type;
480 print_tabs(1, fd);
481 if(print_type(type, fd, tabs, basename, field->name)) return 1;
482 fprintf(fd, " ");
483 fprintf(fd, "%s", field->name);
484 fprintf(fd, ";\n");
485 }
486 fprintf(fd, "} LTT_ALIGN;\n");
487 fprintf(fd, "\n");
488 break;
489 case UNION:
490 for(unsigned int i=0;i<td->fields.position;i++){
491 field_t *field = (field_t*)(td->fields.array[i]);
492 type_descriptor_t *type = field->type;
493 if(type->type_name == NULL) {
494 /* Not a named nested type : we must print its declaration first */
495 if(print_type_declaration(type,
496 fd, 0, basename, field->name)) return 1;
497 }
498 }
499 fprintf(fd, "union lttng_%s", basename);
500 fprintf(fd, " {\n");
501 for(unsigned i=0;i<td->fields.position;i++){
502 field_t *field = (field_t*)(td->fields.array[i]);
503 type_descriptor_t *type = field->type;
504 print_tabs(1, fd);
505 if(print_type(type, fd, tabs, basename, field->name)) return 1;
506 fprintf(fd, " ");
507 fprintf(fd, "%s", field->name);
508 fprintf(fd, ";\n");
509 }
510 fprintf(fd, "} LTT_ALIGN;\n");
511 fprintf(fd, "\n");
512 break;
513 default:
514 dprintf("print_type_declaration : unknown type or nothing to declare.\n");
515 break;
516 }
517
518 return 0;
519 }
520
521
522 /* print type alignment.
523 *
524 * Copied from construct_types_and_fields in LTTV facility.c
525 *
526 * basename is the name which identifies the type (along with a prefix
527 * (possibly)). */
528
529 int print_type_alignment(type_descriptor_t * td, FILE *fd, unsigned int tabs,
530 char *nest_name, char *field_name, char *obj_prefix)
531 {
532 char basename[PATH_MAX];
533 unsigned int basename_len = 0;
534
535 strncpy(basename, nest_name, PATH_MAX);
536 basename_len = strlen(basename);
537
538 /* For a named type, we use the type_name directly */
539 if(td->type_name != NULL) {
540 strncpy(basename, td->type_name, PATH_MAX);
541 basename_len = strlen(basename);
542 } else {
543 /* For a unnamed type, there must be a field name, except for
544 * the array. */
545 if((basename_len != 0)
546 && (basename[basename_len-1] != '_'
547 && field_name != NULL
548 && (field_name[0] != '\0'))) {
549 strncat(basename, "_", PATH_MAX - basename_len);
550 basename_len = strlen(basename);
551 }
552 if(field_name != NULL)
553 strncat(basename, field_name, PATH_MAX - basename_len);
554 }
555
556 if(field_name[0] == '\0') {
557 /* We are in a write function : it's the obj that we must align. */
558 switch(td->type) {
559 case SEQUENCE:
560 fprintf(fd, "lttng_get_alignment_sequence_%s(%s)", basename,
561 obj_prefix);
562 break;
563 case STRUCT:
564 fprintf(fd, "lttng_get_alignment_struct_%s(%s)", basename,
565 obj_prefix);
566 break;
567 case UNION:
568 fprintf(fd, "lttng_get_alignment_union_%s(%s)", basename,
569 obj_prefix);
570 break;
571 case ARRAY:
572 fprintf(fd, "lttng_get_alignment_array_%s(%s)", basename,
573 obj_prefix);
574 case STRING:
575 fprintf(fd, "sizeof(char)");
576 break;
577 default:
578 printf("error : type unexpected\n");
579 return 1;
580 break;
581 }
582 } else {
583
584 switch(td->type) {
585 case INT_FIXED:
586 case UINT_FIXED:
587 case CHAR:
588 case UCHAR:
589 case SHORT:
590 case USHORT:
591 case INT:
592 case UINT:
593 case FLOAT:
594 case POINTER:
595 case LONG:
596 case ULONG:
597 case SIZE_T:
598 case SSIZE_T:
599 case OFF_T:
600 case ENUM:
601 fprintf(fd, "sizeof(");
602 if(print_type(td, fd, 0, basename, "")) return 1;
603 fprintf(fd, ")");
604 break;
605 case STRING:
606 fprintf(fd, "sizeof(char)");
607 break;
608 case SEQUENCE:
609 fprintf(fd, "lttng_get_alignment_sequence_%s(&%s%s)", basename,
610 obj_prefix, field_name);
611 break;
612 case STRUCT:
613 fprintf(fd, "lttng_get_alignment_struct_%s(&%s%s)", basename,
614 obj_prefix, field_name);
615 break;
616 case UNION:
617 fprintf(fd, "lttng_get_alignment_union_%s(&%s%s)", basename,
618 obj_prefix, field_name);
619 break;
620 case ARRAY:
621 fprintf(fd, "lttng_get_alignment_array_%s(%s%s)", basename,
622 obj_prefix, field_name);
623 break;
624 case NONE:
625 printf("error : type NONE unexpected\n");
626 return 1;
627 break;
628 }
629 }
630
631 return 0;
632 }
633
634 /* print type write.
635 *
636 * Copied from construct_types_and_fields in LTTV facility.c
637 *
638 * basename is the name which identifies the type (along with a prefix
639 * (possibly)). */
640
641 int print_type_write(type_descriptor_t * td, FILE *fd, unsigned int tabs,
642 char *nest_name, char *field_name, char *obj_prefix, int get_ptr)
643 {
644 char basename[PATH_MAX];
645 unsigned int basename_len = 0;
646 char get_ptr_char[2] = "";
647
648 strncpy(basename, nest_name, PATH_MAX);
649 basename_len = strlen(basename);
650
651 /* For a named type, we use the type_name directly */
652 if(td->type_name != NULL) {
653 strncpy(basename, td->type_name, PATH_MAX);
654 basename_len = strlen(basename);
655 } else {
656 /* For a unnamed type, there must be a field name, except for
657 * the array. */
658 if((basename_len != 0)
659 && (basename[basename_len-1] != '_'
660 && (field_name[0] != '\0'))) {
661 strncat(basename, "_", PATH_MAX - basename_len);
662 basename_len = strlen(basename);
663 }
664 strncat(basename, field_name, PATH_MAX - basename_len);
665 }
666
667 if(get_ptr) {
668 strcpy(get_ptr_char, "&");
669 }
670
671 switch(td->type) {
672 case INT_FIXED:
673 case UINT_FIXED:
674 case CHAR:
675 case UCHAR:
676 case SHORT:
677 case USHORT:
678 case INT:
679 case UINT:
680 case FLOAT:
681 case POINTER:
682 case LONG:
683 case ULONG:
684 case SIZE_T:
685 case SSIZE_T:
686 case OFF_T:
687 case ENUM:
688 print_tabs(tabs, fd);
689 fprintf(fd, "size = ");
690 fprintf(fd, "sizeof(");
691 if(print_type(td, fd, 0, basename, "")) return 1;
692 fprintf(fd, ");\n");
693 print_tabs(tabs, fd);
694 fprintf(fd, "size += ltt_align(*to+*len, size) + size;\n");
695 print_tabs(tabs, fd);
696 fprintf(fd, "*len += size;");
697 break;
698 case STRING:
699 print_tabs(tabs, fd);
700 fprintf(fd,
701 "lttng_write_string_%s(buffer, to_base, to, from, len, %s%s);\n",
702 basename, obj_prefix, field_name);
703 break;
704 case SEQUENCE:
705 print_tabs(tabs, fd);
706 fprintf(fd,
707 "lttng_write_sequence_%s(buffer, to_base, to, from, len, %s%s%s);",
708 basename, get_ptr_char, obj_prefix, field_name);
709 break;
710 case STRUCT:
711 print_tabs(tabs, fd);
712 fprintf(fd,
713 "lttng_write_struct_%s(buffer, to_base, to, from, len, %s%s%s);",
714 basename, get_ptr_char, obj_prefix, field_name);
715 break;
716 case UNION:
717 print_tabs(tabs, fd);
718 fprintf(fd,
719 "lttng_write_union_%s(buffer, to_base, to, from, len, %s%s%s);",
720 basename, get_ptr_char, obj_prefix, field_name);
721 break;
722 case ARRAY:
723 print_tabs(tabs, fd);
724 fprintf(fd,
725 "lttng_write_array_%s(buffer, to_base, to, from, len, %s%s);",
726 basename, obj_prefix, field_name);
727 break;
728 case NONE:
729 printf("Error : type NONE unexpected\n");
730 return 1;
731 break;
732 }
733
734 return 0;
735 }
736
737
738
739 /* print type alignment function.
740 *
741 * Copied from construct_types_and_fields in LTTV facility.c
742 *
743 * basename is the name which identifies the type (along with a prefix
744 * (possibly)). */
745
746 int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
747 unsigned int tabs,
748 char *nest_name, char *field_name)
749 {
750 char basename[PATH_MAX];
751 unsigned int basename_len = 0;
752
753 strncpy(basename, nest_name, PATH_MAX);
754 basename_len = strlen(basename);
755
756 /* For a named type, we use the type_name directly */
757 if(td->type_name != NULL) {
758 strncpy(basename, td->type_name, PATH_MAX);
759 basename_len = strlen(basename);
760 } else {
761 /* For a unnamed type, there must be a field name, except for
762 * the array. */
763 if((basename_len != 0)
764 && (basename[basename_len-1] != '_'
765 && (field_name[0] != '\0'))) {
766 strncat(basename, "_", PATH_MAX - basename_len);
767 basename_len = strlen(basename);
768 }
769 strncat(basename, field_name, PATH_MAX - basename_len);
770 }
771
772 switch(td->type) {
773 case SEQUENCE:
774 /* Function header */
775 fprintf(fd, "static inline size_t lttng_get_alignment_sequence_%s(\n",
776 basename);
777 print_tabs(2, fd);
778 if(print_type(td, fd, 0, basename, "")) return 1;
779 fprintf(fd, " *obj)\n");
780 fprintf(fd, "{\n");
781 print_tabs(1, fd);
782 fprintf(fd, "size_t align=0, localign;");
783 fprintf(fd, "\n");
784 print_tabs(1, fd);
785 fprintf(fd, "localign = ");
786 if(print_type_alignment(((field_t*)td->fields.array[0])->type,
787 fd, 0, basename, "len", "obj->")) return 1;
788 fprintf(fd, ";\n");
789 print_tabs(1, fd);
790 fprintf(fd, "align = max(align, localign);\n");
791 fprintf(fd, "\n");
792 print_tabs(1, fd);
793 fprintf(fd, "localign = ");
794 if(print_type_alignment(((field_t*)td->fields.array[1])->type,
795 fd, 0, basename, "array[0]", "obj->")) return 1;
796 fprintf(fd, ";\n");
797 print_tabs(1, fd);
798 fprintf(fd, "align = max(align, localign);\n");
799 fprintf(fd, "\n");
800 print_tabs(1, fd);
801 fprintf(fd, "return align;\n");
802 break;
803 case STRUCT:
804 /* Function header */
805 fprintf(fd, "static inline size_t lttng_get_alignment_struct_%s(\n",
806 basename);
807 print_tabs(2, fd);
808 if(print_type(td, fd, 0, basename, "")) return 1;
809 fprintf(fd, " *obj)\n");
810 fprintf(fd, "{\n");
811 print_tabs(1, fd);
812 fprintf(fd, "size_t align=0, localign;");
813 fprintf(fd, "\n");
814 for(unsigned int i=0;i<td->fields.position;i++){
815 field_t *field = (field_t*)(td->fields.array[i]);
816 type_descriptor_t *type = field->type;
817 print_tabs(1, fd);
818 fprintf(fd, "localign = ");
819 if(print_type_alignment(type, fd, 0, basename, field->name, "obj->"))
820 return 1;
821 fprintf(fd, ";\n");
822 print_tabs(1, fd);
823 fprintf(fd, "align = max(align, localign);\n");
824 fprintf(fd, "\n");
825 }
826 print_tabs(1, fd);
827 fprintf(fd, "return align;\n");
828
829 break;
830 case UNION:
831 /* Function header */
832 fprintf(fd, "static inline size_t lttng_get_alignment_union_%s(\n",
833 basename);
834 print_tabs(2, fd);
835 if(print_type(td, fd, 0, basename, "")) return 1;
836 fprintf(fd, " *obj)\n");
837 fprintf(fd, "{\n");
838 print_tabs(1, fd);
839 fprintf(fd, "size_t align=0, localign;");
840 fprintf(fd, "\n");
841 for(unsigned int i=0;i<td->fields.position;i++){
842 field_t *field = (field_t*)(td->fields.array[i]);
843 type_descriptor_t *type = field->type;
844 print_tabs(1, fd);
845 fprintf(fd, "localign = ");
846 if(print_type_alignment(type, fd, 0, basename, field->name, "obj->"))
847 return 1;
848 fprintf(fd, ";\n");
849 print_tabs(1, fd);
850 fprintf(fd, "align = max(align, localign);\n");
851 fprintf(fd, "\n");
852 }
853 print_tabs(1, fd);
854 fprintf(fd, "return align;\n");
855
856 break;
857 case ARRAY:
858 /* Function header */
859 fprintf(fd, "static inline size_t lttng_get_alignment_array_%s(\n",
860 basename);
861 print_tabs(2, fd);
862 if(print_type(td, fd, 0, basename, "")) return 1;
863 fprintf(fd, " obj)\n");
864 fprintf(fd, "{\n");
865 print_tabs(1, fd);
866 fprintf(fd, "return \n");
867 if(print_type_alignment(((field_t*)td->fields.array[0])->type,
868 fd, 0, basename, "", "obj[0]"))
869 return 1;
870 fprintf(fd, ";\n");
871 break;
872 default:
873 dprintf("print_type_alignment_fct : type has no alignment function.\n");
874 return 0;
875 break;
876 }
877
878
879 /* Function footer */
880 fprintf(fd, "}\n");
881 fprintf(fd, "\n");
882
883 return 0;
884 }
885
886 /* print type write function.
887 *
888 * Copied from construct_types_and_fields in LTTV facility.c
889 *
890 * basename is the name which identifies the type (along with a prefix
891 * (possibly)). */
892
893 int print_type_write_fct(type_descriptor_t * td, FILE *fd, unsigned int tabs,
894 char *nest_name, char *field_name)
895 {
896 char basename[PATH_MAX];
897 unsigned int basename_len = 0;
898
899 strncpy(basename, nest_name, PATH_MAX);
900 basename_len = strlen(basename);
901
902 /* For a named type, we use the type_name directly */
903 if(td->type_name != NULL) {
904 strncpy(basename, td->type_name, PATH_MAX);
905 basename_len = strlen(basename);
906 } else {
907 /* For a unnamed type, there must be a field name, except for
908 * the array. */
909 if((basename_len != 0)
910 && (basename[basename_len-1] != '_'
911 && (field_name[0] != '\0'))) {
912 strncat(basename, "_", PATH_MAX - basename_len);
913 basename_len = strlen(basename);
914 }
915 strncat(basename, field_name, PATH_MAX - basename_len);
916 }
917
918 switch(td->type) {
919 case SEQUENCE:
920 case STRUCT:
921 case UNION:
922 case ARRAY:
923 case STRING:
924 break;
925 default:
926 dprintf("print_type_write_fct : type has no write function.\n");
927 return 0;
928 break;
929 }
930
931 /* Print header */
932 switch(td->type) {
933 case SEQUENCE:
934 fprintf(fd, "static inline void lttng_write_sequence_%s(\n",
935 basename);
936 break;
937 case STRUCT:
938 fprintf(fd, "static inline void lttng_write_struct_%s(\n", basename);
939 break;
940 case UNION:
941 fprintf(fd, "static inline void lttng_write_union_%s(\n", basename);
942 break;
943 case ARRAY:
944 fprintf(fd, "static inline void lttng_write_array_%s(\n", basename);
945 break;
946 case STRING:
947 fprintf(fd, "static inline void lttng_write_string_%s(\n", basename);
948 break;
949 default:
950 printf("print_type_write_fct : type has no write function.\n");
951 break;
952 }
953
954 print_tabs(2, fd);
955 fprintf(fd, "void *buffer,\n");
956 print_tabs(2, fd);
957 fprintf(fd, "size_t *to_base,\n");
958 print_tabs(2, fd);
959 fprintf(fd, "size_t *to,\n");
960 print_tabs(2, fd);
961 fprintf(fd, "const void **from,\n");
962 print_tabs(2, fd);
963 fprintf(fd, "size_t *len,\n");
964 print_tabs(2, fd);
965 if(print_type(td, fd, 0, basename, "")) return 1;
966
967 switch(td->type) {
968 case SEQUENCE:
969 fprintf(fd, " *obj)\n");
970 break;
971 case STRUCT:
972 fprintf(fd, " *obj)\n");
973 break;
974 case UNION:
975 fprintf(fd, " *obj)\n");
976 break;
977 case ARRAY:
978 fprintf(fd, " obj)\n");
979 break;
980 case STRING:
981 fprintf(fd, " obj)\n");
982 break;
983 default:
984 printf("print_type_write_fct : type has no write function.\n");
985 break;
986 }
987
988 fprintf(fd, "{\n");
989 print_tabs(1, fd);
990 fprintf(fd, "size_t align, size;\n");
991 fprintf(fd, "\n");
992
993 switch(td->type) {
994 case SEQUENCE:
995 case STRING:
996 print_tabs(1, fd);
997 fprintf(fd, "/* Flush pending memcpy */\n");
998 print_tabs(1, fd);
999 fprintf(fd, "if(*len != 0) {\n");
1000 print_tabs(2, fd);
1001 fprintf(fd, "if(buffer != NULL)\n");
1002 print_tabs(3, fd);
1003 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
1004 print_tabs(1, fd);
1005 fprintf(fd, "}\n");
1006 print_tabs(1, fd);
1007 fprintf(fd, "*to += *len;\n");
1008 print_tabs(1, fd);
1009 fprintf(fd, "*len = 0;\n");
1010 fprintf(fd, "\n");
1011 break;
1012 case STRUCT:
1013 case UNION:
1014 case ARRAY:
1015 break;
1016 default:
1017 printf("print_type_write_fct : type has no write function.\n");
1018 break;
1019 }
1020
1021 print_tabs(1, fd);
1022 fprintf(fd, "align = ");
1023 if(print_type_alignment(td, fd, 0, basename, "", "obj")) return 1;
1024 fprintf(fd, ";\n");
1025 fprintf(fd, "\n");
1026 print_tabs(1, fd);
1027 fprintf(fd, "if(*len == 0) {\n");
1028 print_tabs(2, fd);
1029 fprintf(fd, "*to += ltt_align(*to, align); /* align output */\n");
1030 print_tabs(1, fd);
1031 fprintf(fd, "} else {\n");
1032 print_tabs(2, fd);
1033 fprintf(fd, "*len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */\n");
1034 print_tabs(1, fd);
1035 fprintf(fd, "}\n");
1036 fprintf(fd, "\n");
1037
1038 /* First, check if the type has a fixed size. If it is the case, then the size
1039 * to write is know by the compiler : simply use a sizeof() */
1040 if(has_type_fixed_size(td)) {
1041 print_tabs(1, fd);
1042 fprintf(fd, "/* Contains only fixed size fields : use compiler sizeof() */\n");
1043 fprintf(fd, "\n");
1044 print_tabs(1, fd);
1045 fprintf(fd, "size = sizeof(");
1046 if(print_type(td, fd, 0, basename, field_name)) return 1;
1047 fprintf(fd, ");\n");
1048 print_tabs(1, fd);
1049 fprintf(fd, "*len += size;\n");
1050 } else {
1051 /* The type contains nested variable size subtypes :
1052 * we must write field by field. */
1053 print_tabs(1, fd);
1054 fprintf(fd, "/* Contains variable sized fields : must explode the structure */\n");
1055 fprintf(fd, "\n");
1056
1057 switch(td->type) {
1058 case SEQUENCE:
1059 print_tabs(1, fd);
1060 fprintf(fd, "/* Copy members */\n");
1061 // print_tabs(1, fd);
1062 // fprintf(fd, "size = sizeof(\n");
1063 if(print_type_write(((field_t*)td->fields.array[0])->type,
1064 fd, 1, basename, "len", "obj->", 1)) return 1;
1065 fprintf(fd, "\n");
1066 // fprintf(fd, ");\n");
1067 // print_tabs(1, fd);
1068 // fprintf(fd, "*to += ltt_align(*to, size);\n");
1069 print_tabs(1, fd);
1070 fprintf(fd, "if(buffer != NULL)\n");
1071 print_tabs(2, fd);
1072 fprintf(fd, "memcpy(buffer+*to_base+*to, &obj->len, size);\n");
1073 print_tabs(1, fd);
1074 fprintf(fd, "*to += size;\n");
1075 fprintf(fd, "\n");
1076
1077 /* Write the child : varlen child or not ? */
1078 if(has_type_fixed_size(((field_t*)td->fields.array[1])->type)) {
1079 /* Fixed size len child : use a multiplication of its size */
1080 // print_tabs(1, fd);
1081 // fprintf(fd, "size = sizeof(\n");
1082 if(print_type_write(((field_t*)td->fields.array[1])->type,
1083 fd, 1, basename, "array[0]", "obj->", 1)) return 1;
1084 // fprintf(fd, ");\n");
1085 // print_tabs(1, fd);
1086 fprintf(fd, "*to += ltt_align(*to, size);\n");
1087 print_tabs(1, fd);
1088 fprintf(fd, "size = obj->len * size;\n");
1089 print_tabs(1, fd);
1090 fprintf(fd, "if(buffer != NULL)\n");
1091 print_tabs(2, fd);
1092 fprintf(fd, "memcpy(buffer+*to_base+*to, obj->array, size);\n");
1093 print_tabs(1, fd);
1094 fprintf(fd, "*to += size;\n");
1095 fprintf(fd, "\n");
1096 } else {
1097 print_tabs(1, fd);
1098 fprintf(fd, "/* Variable length child : iter. */\n");
1099 print_tabs(1, fd);
1100 fprintf(fd, "for(unsigned int i=0; i<obj->len; i++) {\n");
1101 if(print_type_write(((field_t*)td->fields.array[1])->type,
1102 fd, 2, basename, "array[i]", "obj->", 1)) return 1;
1103 print_tabs(1, fd);
1104 fprintf(fd, "}\n");
1105 }
1106 fprintf(fd, "\n");
1107 print_tabs(1, fd);
1108 fprintf(fd, "/* Realign the *to_base on arch size, set *to to 0 */\n");
1109 print_tabs(1, fd);
1110 fprintf(fd, "*to = ltt_align(*to, sizeof(void *));\n");
1111 print_tabs(1, fd);
1112 fprintf(fd, "*to_base = *to_base+*to;\n");
1113 print_tabs(1, fd);
1114 fprintf(fd, "*to = 0;\n");
1115 fprintf(fd, "\n");
1116 print_tabs(1, fd);
1117 fprintf(fd, "/* Put source *from just after the C sequence */\n");
1118 print_tabs(1, fd);
1119 fprintf(fd, "*from = obj+1;\n");
1120 break;
1121 case STRING:
1122 print_tabs(1, fd);
1123 fprintf(fd, "size = strlen(obj) + 1; /* Include final NULL char. */\n");
1124 print_tabs(1, fd);
1125 fprintf(fd, "if(buffer != NULL)\n");
1126 print_tabs(2, fd);
1127 fprintf(fd, "memcpy(buffer+*to_base+*to, obj, size);\n");
1128 print_tabs(1, fd);
1129 fprintf(fd, "*to += size;\n");
1130 fprintf(fd, "\n");
1131 print_tabs(1, fd);
1132 fprintf(fd, "/* Realign the *to_base on arch size, set *to to 0 */\n");
1133 print_tabs(1, fd);
1134 fprintf(fd, "*to = ltt_align(*to, sizeof(void *));\n");
1135 print_tabs(1, fd);
1136 fprintf(fd, "*to_base = *to_base+*to;\n");
1137 print_tabs(1, fd);
1138 fprintf(fd, "*to = 0;\n");
1139 fprintf(fd, "\n");
1140 print_tabs(1, fd);
1141 fprintf(fd, "/* Put source *from just after the C string */\n");
1142 print_tabs(1, fd);
1143 fprintf(fd, "*from += size;\n");
1144 break;
1145 case STRUCT:
1146 for(unsigned int i=0;i<td->fields.position;i++){
1147 field_t *field = (field_t*)(td->fields.array[i]);
1148 type_descriptor_t *type = field->type;
1149 if(print_type_write(type,
1150 fd, 1, basename, field->name, "obj->", 1)) return 1;
1151 fprintf(fd, "\n");
1152 }
1153 break;
1154 case UNION:
1155 printf("ERROR : A union CANNOT contain a variable size child.\n");
1156 return 1;
1157 break;
1158 case ARRAY:
1159 /* Write the child : varlen child or not ? */
1160 if(has_type_fixed_size(((field_t*)td->fields.array[0])->type)) {
1161 /* Error : if an array has a variable size, then its child must also
1162 * have a variable size. */
1163 assert(0);
1164 } else {
1165 print_tabs(1, fd);
1166 fprintf(fd, "/* Variable length child : iter. */\n");
1167 print_tabs(1, fd);
1168 fprintf(fd, "for(unsigned int i=0; i<LTTNG_ARRAY_SIZE_%s; i++) {\n", basename);
1169 if(print_type_write(((field_t*)td->fields.array[0])->type,
1170 fd, 2, basename, "", "obj->array[i]", 1)) return 1;
1171 print_tabs(1, fd);
1172 fprintf(fd, "}\n");
1173 }
1174 break;
1175 default:
1176 printf("print_type_write_fct : type has no write function.\n");
1177 break;
1178 }
1179
1180
1181 }
1182
1183
1184 /* Function footer */
1185 fprintf(fd, "}\n");
1186 fprintf(fd, "\n");
1187 return 0;
1188 }
1189
1190
1191
1192 /* Print the logging function of an event. This is the core of genevent */
1193 int print_event_logging_function(char *basename, facility_t *fac,
1194 event_t *event, FILE *fd)
1195 {
1196 fprintf(fd, "static inline void trace_%s(\n", basename);
1197 int has_argument = 0;
1198
1199 /* Does it support per trace tracing ? */
1200 if(event->per_trace) {
1201 print_tabs(2, fd);
1202 fprintf(fd, "struct ltt_trace_struct *dest_trace");
1203 has_argument = 1;
1204 }
1205
1206 /* Does it support per tracefile tracing ? */
1207 if(event->per_tracefile) {
1208 if(has_argument) {
1209 fprintf(fd, ",");
1210 fprintf(fd, "\n");
1211 }
1212 fprintf(fd, "unsigned int tracefile_index");
1213 has_argument = 1;
1214 }
1215
1216 for(unsigned int j = 0; j < event->fields.position; j++) {
1217 /* For each field, print the function argument */
1218 field_t *f = (field_t*)event->fields.array[j];
1219 type_descriptor_t *t = f->type;
1220 if(has_argument) {
1221 fprintf(fd, ",");
1222 fprintf(fd, "\n");
1223 }
1224 if(print_arg(t, fd, 2, basename, f->name)) return 1;
1225 has_argument = 1;
1226 }
1227 if(!has_argument) {
1228 print_tabs(2, fd);
1229 fprintf(fd, "void");
1230 }
1231 fprintf(fd,")\n");
1232 fprintf(fd,
1233 "#if (!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_%s))\n",
1234 fac->capname);
1235 fprintf(fd, "{\n");
1236 fprintf(fd, "}\n");
1237 fprintf(fd,"#else\n");
1238 fprintf(fd, "{\n");
1239 /* Print the function variables */
1240 print_tabs(1, fd);
1241 fprintf(fd, "unsigned int index;\n");
1242 print_tabs(1, fd);
1243 fprintf(fd, "struct ltt_channel_struct *channel;\n");
1244 print_tabs(1, fd);
1245 fprintf(fd, "struct ltt_trace_struct *trace;\n");
1246 print_tabs(1, fd);
1247 fprintf(fd, "struct rchan_buf *relayfs_buf;\n");
1248 print_tabs(1, fd);
1249 fprintf(fd, "void *buffer = NULL;\n");
1250 print_tabs(1, fd);
1251 fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
1252 print_tabs(1, fd);
1253 fprintf(fd, "size_t *to_base = &real_to_base;\n");
1254 print_tabs(1, fd);
1255 fprintf(fd, "size_t real_to = 0;\n");
1256 print_tabs(1, fd);
1257 fprintf(fd, "size_t *to = &real_to;\n");
1258 print_tabs(1, fd);
1259 fprintf(fd, "size_t real_len = 0;\n");
1260 print_tabs(1, fd);
1261 fprintf(fd, "size_t *len = &real_len;\n");
1262 print_tabs(1, fd);
1263 fprintf(fd, "size_t reserve_size;\n");
1264 print_tabs(1, fd);
1265 fprintf(fd, "size_t slot_size;\n");
1266 print_tabs(1, fd);
1267 if(event->fields.position > 0) {
1268 fprintf(fd, "size_t size;\n");
1269 print_tabs(1, fd);
1270 fprintf(fd, "const void *real_from;\n");
1271 print_tabs(1, fd);
1272 fprintf(fd, "const void **from = &real_from;\n");
1273 print_tabs(1, fd);
1274 }
1275 fprintf(fd, "cycles_t tsc;\n");
1276 print_tabs(1, fd);
1277 fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n");
1278 fprintf(fd, "\n");
1279
1280 print_tabs(1, fd);
1281 fprintf(fd, "if(ltt_traces.num_active_traces == 0) return;\n");
1282 fprintf(fd, "\n");
1283
1284 /* Calculate event variable len + event data alignment offset.
1285 * Assume that the padding for alignment starts at a void*
1286 * address.
1287 * This excludes the header size and alignment. */
1288
1289 print_tabs(1, fd);
1290 fprintf(fd, "/* For each field, calculate the field size. */\n");
1291 print_tabs(1, fd);
1292 fprintf(fd, "/* size = *to_base + *to + *len */\n");
1293 print_tabs(1, fd);
1294 fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
1295 print_tabs(1, fd);
1296 fprintf(fd, " * sizeof(void *) address. */\n");
1297 fprintf(fd, "\n");
1298
1299 for(unsigned int i=0;i<event->fields.position;i++){
1300 field_t *field = (field_t*)(event->fields.array[i]);
1301 type_descriptor_t *type = field->type;
1302 /* Set from */
1303 print_tabs(1, fd);
1304 switch(type->type) {
1305 case SEQUENCE:
1306 case UNION:
1307 case ARRAY:
1308 case STRUCT:
1309 case STRING:
1310 fprintf(fd, "*from = %s;\n", field->name);
1311 break;
1312 default:
1313 fprintf(fd, "*from = &%s;\n", field->name);
1314 break;
1315 }
1316
1317 if(print_type_write(type,
1318 fd, 1, basename, field->name, "", 0)) return 1;
1319 fprintf(fd, "\n");
1320 }
1321 print_tabs(1, fd);
1322 fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
1323 print_tabs(1, fd);
1324 fprintf(fd, "*to_base = *to = *len = 0;\n");
1325 fprintf(fd, "\n");
1326
1327 /* Take locks : make sure the trace does not vanish while we write on
1328 * it. A simple preemption disabling is enough (using rcu traces). */
1329 print_tabs(1, fd);
1330 fprintf(fd, "preempt_disable();\n");
1331 print_tabs(1, fd);
1332 fprintf(fd, "ltt_nesting[smp_processor_id()]++;\n");
1333
1334 /* Get facility index */
1335
1336 if(event->per_tracefile) {
1337 print_tabs(1, fd);
1338 fprintf(fd, "index = tracefile_index;\n");
1339 } else {
1340 print_tabs(1, fd);
1341 fprintf(fd,
1342 "index = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
1343 "\t\t\t\t\t\tevent_%s_%s);\n",
1344 fac->name, fac->checksum, fac->name, event->name);
1345 }
1346 fprintf(fd,"\n");
1347
1348
1349 /* For each trace */
1350 print_tabs(1, fd);
1351 fprintf(fd, "list_for_each_entry_rcu(trace, &ltt_traces.head, list) {\n");
1352 print_tabs(2, fd);
1353 fprintf(fd, "if(!trace->active) continue;\n\n");
1354
1355 if(event->per_trace) {
1356 print_tabs(2, fd);
1357 fprintf(fd, "if(dest_trace != trace) continue;\n\n");
1358 }
1359
1360 print_tabs(2, fd);
1361 fprintf(fd, "channel = ltt_get_channel_from_index(trace, index);\n");
1362 print_tabs(2, fd);
1363 fprintf(fd, "relayfs_buf = channel->rchan->buf[smp_processor_id()];\n");
1364 fprintf(fd, "\n");
1365
1366
1367 /* Relay reserve */
1368 /* If error, increment event lost counter (done by ltt_reserve_slot) and
1369 * return */
1370 print_tabs(2, fd);
1371 fprintf(fd, "slot_size = 0;\n");
1372 print_tabs(2, fd);
1373 fprintf(fd, "buffer = ltt_reserve_slot(trace, relayfs_buf,\n");
1374 print_tabs(3, fd);
1375 fprintf(fd, "reserve_size, &slot_size, &tsc,\n");
1376 print_tabs(3, fd);
1377 fprintf(fd, "&before_hdr_pad, &after_hdr_pad, &header_size);\n");
1378 /* If error, return */
1379 print_tabs(2, fd);
1380 fprintf(fd, "if(!buffer) return;\n\n");
1381 /* Write event header */
1382 print_tabs(2, fd);
1383 fprintf(fd, "ltt_write_event_header(trace, channel, buffer,\n");
1384 print_tabs(3, fd);
1385 fprintf(fd, "ltt_facility_%s_%X, event_%s_%s,\n", fac->name, fac->checksum,
1386 fac->name, event->name);
1387 print_tabs(3, fd);
1388 fprintf(fd, "reserve_size, before_hdr_pad, tsc);\n");
1389 print_tabs(2, fd);
1390 fprintf(fd, "*to_base += before_hdr_pad + after_hdr_pad + header_size;\n");
1391
1392 /* write data : assume stack alignment is the same as struct alignment. */
1393
1394 for(unsigned int i=0;i<event->fields.position;i++){
1395 field_t *field = (field_t*)(event->fields.array[i]);
1396 type_descriptor_t *type = field->type;
1397
1398 /* Set from */
1399 print_tabs(2, fd);
1400 switch(type->type) {
1401 case SEQUENCE:
1402 case UNION:
1403 case ARRAY:
1404 case STRUCT:
1405 case STRING:
1406 fprintf(fd, "*from = %s;\n", field->name);
1407 break;
1408 default:
1409 fprintf(fd, "*from = &%s;\n", field->name);
1410 break;
1411 }
1412
1413
1414 if(print_type_write(type,
1415 fd, 2, basename, field->name, "", 0)) return 1;
1416 fprintf(fd, "\n");
1417
1418 /* Don't forget to flush pending memcpy */
1419 print_tabs(2, fd);
1420 fprintf(fd, "/* Flush pending memcpy */\n");
1421 print_tabs(2, fd);
1422 fprintf(fd, "if(len != 0) {\n");
1423 print_tabs(3, fd);
1424 fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
1425 print_tabs(3, fd);
1426 fprintf(fd, "*to += *len;\n");
1427 //print_tabs(3, fd);
1428 //fprintf(fd, "from += len;\n");
1429 print_tabs(3, fd);
1430 fprintf(fd, "*len = 0;\n");
1431 print_tabs(2, fd);
1432 fprintf(fd, "}\n");
1433 fprintf(fd, "\n");
1434 }
1435
1436
1437 /* commit */
1438 print_tabs(2, fd);
1439 fprintf(fd, "ltt_commit_slot(relayfs_buf, buffer, slot_size);\n\n");
1440
1441 print_tabs(1, fd);
1442 fprintf(fd, "}\n\n");
1443
1444 /* Release locks */
1445 print_tabs(1, fd);
1446 fprintf(fd, "ltt_nesting[smp_processor_id()]--;\n");
1447 print_tabs(1, fd);
1448 fprintf(fd, "preempt_enable_no_resched();\n");
1449
1450 fprintf(fd, "}\n");
1451 fprintf(fd, "#endif //(!defined(CONFIG_LTT) || !defined(CONFIG_LTT_FACILITY_%s))\n\n",
1452 fac->capname);
1453 return 0;
1454 }
1455
1456
1457 /* ltt-facility-name.h : main logging header.
1458 * log_header */
1459
1460 void print_log_header_head(facility_t *fac, FILE *fd)
1461 {
1462 fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
1463 fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
1464 fprintf(fd, "#include <linux/types.h>\n");
1465 fprintf(fd, "#include <linux/ltt/ltt-facility-id-%s.h>\n", fac->name);
1466 fprintf(fd, "#include <linux/ltt-core.h>\n");
1467 fprintf(fd, "\n");
1468 }
1469
1470
1471
1472 int print_log_header_types(facility_t *fac, FILE *fd)
1473 {
1474 sequence_t *types = &fac->named_types.values;
1475 fprintf(fd, "/* Named types */\n");
1476 fprintf(fd, "\n");
1477
1478 for(unsigned int i = 0; i < types->position; i++) {
1479 /* For each named type, print the definition */
1480 if(print_type_declaration(types->array[i], fd,
1481 0, "", "")) return 1;
1482 /* Print also the align function */
1483 if(print_type_alignment_fct(types->array[i], fd,
1484 0, "", "")) return 1;
1485 /* Print also the write function */
1486 if(print_type_write_fct(types->array[i], fd,
1487 0, "", "")) return 1;
1488 }
1489 return 0;
1490 }
1491
1492 int print_log_header_events(facility_t *fac, FILE *fd)
1493 {
1494 sequence_t *events = &fac->events;
1495 char basename[PATH_MAX];
1496 unsigned int facname_len;
1497
1498 strncpy(basename, fac->name, PATH_MAX);
1499 facname_len = strlen(basename);
1500 strncat(basename, "_", PATH_MAX-facname_len);
1501 facname_len = strlen(basename);
1502
1503 for(unsigned int i = 0; i < events->position; i++) {
1504 event_t *event = (event_t*)events->array[i];
1505 strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
1506
1507 /* For each event, print structure, and then logging function */
1508 fprintf(fd, "/* Event %s structures */\n",
1509 event->name);
1510 for(unsigned int j = 0; j < event->fields.position; j++) {
1511 /* For each unnamed type, print the definition */
1512 field_t *f = (field_t*)event->fields.array[j];
1513 type_descriptor_t *t = f->type;
1514 if(t->type_name == NULL) {
1515 if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
1516 /* Print also the align function */
1517 if((print_type_alignment_fct(t, fd, 0, basename, f->name))) return 1;
1518 /* Print also the write function */
1519 if((print_type_write_fct(t, fd, 0, basename, f->name))) return 1;
1520 }
1521 }
1522
1523 fprintf(fd, "\n");
1524
1525 fprintf(fd, "/* Event %s logging function */\n",
1526 event->name);
1527
1528 if(print_event_logging_function(basename, fac, event, fd)) return 1;
1529
1530 fprintf(fd, "\n");
1531 }
1532
1533 return 0;
1534 }
1535
1536
1537 void print_log_header_tail(facility_t *fac, FILE *fd)
1538 {
1539 fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
1540 }
1541
1542 int print_log_header(facility_t *fac)
1543 {
1544 char filename[PATH_MAX];
1545 unsigned int filename_size = 0;
1546 FILE *fd;
1547 dprintf("%s\n", fac->name);
1548
1549 strcpy(filename, "ltt-facility-");
1550 filename_size = strlen(filename);
1551
1552 strncat(filename, fac->name, PATH_MAX - filename_size);
1553 filename_size = strlen(filename);
1554
1555 strncat(filename, ".h", PATH_MAX - filename_size);
1556 filename_size = strlen(filename);
1557
1558
1559 fd = fopen(filename, "w");
1560 if(fd == NULL) {
1561 printf("Error opening file %s for writing : %s\n",
1562 filename, strerror(errno));
1563 return errno;
1564 }
1565
1566 /* Print file head */
1567 print_log_header_head(fac, fd);
1568
1569 /* print named types in declaration order */
1570 if(print_log_header_types(fac, fd)) return 1;
1571
1572 /* Print events */
1573 if(print_log_header_events(fac, fd)) return 1;
1574
1575 /* Print file tail */
1576 print_log_header_tail(fac, fd);
1577
1578
1579 fclose(fd);
1580
1581 return 0;
1582 }
1583
1584
1585 /* ltt-facility-id-name.h : facility id.
1586 * log_id_header */
1587 int print_id_header(facility_t *fac)
1588 {
1589 char filename[PATH_MAX];
1590 unsigned int filename_size = 0;
1591 FILE *fd;
1592 char basename[PATH_MAX];
1593 char basename_len = 0;
1594
1595 dprintf("%s\n", fac->name);
1596
1597 strcpy(filename, "ltt-facility-id-");
1598 filename_size = strlen(filename);
1599
1600 strncat(filename, fac->name, PATH_MAX - filename_size);
1601 filename_size = strlen(filename);
1602
1603 strncat(filename, ".h", PATH_MAX - filename_size);
1604 filename_size = strlen(filename);
1605
1606
1607 fd = fopen(filename, "w");
1608 if(fd == NULL) {
1609 printf("Error opening file %s for writing : %s\n",
1610 filename, strerror(errno));
1611 return errno;
1612 }
1613
1614 fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
1615 fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
1616 fprintf(fd, "#ifdef CONFIG_LTT\n");
1617
1618 fprintf(fd,"#include <linux/ltt-facilities.h>\n\n");
1619
1620 fprintf(fd,"/**** facility handle ****/\n\n");
1621 fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
1622 fac->name, fac->checksum);
1623 fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
1624
1625 strncpy(basename, fac->name, PATH_MAX);
1626 basename_len = strlen(basename);
1627 strncat(basename, "_", PATH_MAX - basename_len);
1628 basename_len++;
1629
1630 fprintf(fd,"/**** event index ****/\n\n");
1631 fprintf(fd,"enum %s_event {\n",fac->name);
1632
1633 for(unsigned int i = 0; i < fac->events.position; i++) {
1634 event_t *event = (event_t*)fac->events.array[i];
1635 strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
1636 print_tabs(1, fd);
1637 fprintf(fd, "event_%s,\n", basename);
1638 }
1639 print_tabs(1, fd);
1640 fprintf(fd, "facility_%s_num_events\n", fac->name);
1641 fprintf(fd, "};\n");
1642 fprintf(fd, "\n");
1643
1644
1645 fprintf(fd, "#endif //CONFIG_LTT\n");
1646 fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
1647
1648
1649 fclose(fd);
1650
1651 return 0;
1652 }
1653
1654
1655 /* ltt-facility-loader-name.h : facility specific loader info.
1656 * loader_header */
1657 int print_loader_header(facility_t *fac)
1658 {
1659 char filename[PATH_MAX];
1660 unsigned int filename_size = 0;
1661 FILE *fd;
1662 dprintf("%s\n", fac->name);
1663
1664 strcpy(filename, "ltt-facility-loader-");
1665 filename_size = strlen(filename);
1666
1667 strncat(filename, fac->name, PATH_MAX - filename_size);
1668 filename_size = strlen(filename);
1669
1670 strncat(filename, ".h", PATH_MAX - filename_size);
1671 filename_size = strlen(filename);
1672
1673
1674 fd = fopen(filename, "w");
1675 if(fd == NULL) {
1676 printf("Error opening file %s for writing : %s\n",
1677 filename, strerror(errno));
1678 return errno;
1679 }
1680
1681 fprintf(fd, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
1682 fprintf(fd, "#define _LTT_FACILITY_LOADER_%s_H_\n\n", fac->capname);
1683 fprintf(fd, "#ifdef CONFIG_LTT\n\n");
1684 fprintf(fd,"#include <linux/ltt-facilities.h>\n");
1685 fprintf(fd,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n",
1686 fac->name);
1687 fprintf(fd,"ltt_facility_t\tltt_facility_%s;\n", fac->name);
1688 fprintf(fd,"ltt_facility_t\tltt_facility_%s_%X;\n\n",
1689 fac->name, fac->checksum);
1690
1691 fprintf(fd,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
1692 fac->name);
1693 fprintf(fd,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
1694 fac->name, fac->checksum);
1695 fprintf(fd,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", fac->checksum);
1696 fprintf(fd,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", fac->name);
1697 fprintf(fd,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\tfacility_%s_num_events\n\n",
1698 fac->name);
1699 fprintf(fd, "#endif //CONFIG_LTT\n\n");
1700 fprintf(fd, "#endif //_LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
1701
1702 fclose(fd);
1703
1704 return 0;
1705 }
1706
1707 /* ltt-facility-loader-name.c : generic faciilty loader
1708 * loader_c */
1709 int print_loader_c(facility_t *fac)
1710 {
1711 char filename[PATH_MAX];
1712 unsigned int filename_size = 0;
1713 FILE *fd;
1714 dprintf("%s\n", fac->name);
1715
1716 strcpy(filename, "ltt-facility-loader-");
1717 filename_size = strlen(filename);
1718
1719 strncat(filename, fac->name, PATH_MAX - filename_size);
1720 filename_size = strlen(filename);
1721
1722 strncat(filename, ".c", PATH_MAX - filename_size);
1723 filename_size = strlen(filename);
1724
1725
1726 fd = fopen(filename, "w");
1727 if(fd == NULL) {
1728 printf("Error opening file %s for writing : %s\n",
1729 filename, strerror(errno));
1730 return errno;
1731 }
1732
1733 fprintf(fd, "/*\n");
1734 fprintf(fd, " * ltt-facility-loader-%s.c\n", fac->name);
1735 fprintf(fd, " *\n");
1736 fprintf(fd, " * (C) Copyright 2005 - \n");
1737 fprintf(fd, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
1738 fprintf(fd, " *\n");
1739 fprintf(fd, " * Contains the LTT facility loader.\n");
1740 fprintf(fd, " *\n");
1741 fprintf(fd, " */\n");
1742 fprintf(fd, "\n");
1743 fprintf(fd, "\n");
1744 fprintf(fd, "#include <linux/ltt-facilities.h>\n");
1745 fprintf(fd, "#include <linux/module.h>\n");
1746 fprintf(fd, "#include <linux/init.h>\n");
1747 fprintf(fd, "#include <linux/config.h>\n");
1748 fprintf(fd, "#include \"ltt-facility-loader-%s.h\"\n", fac->name);
1749 fprintf(fd, "\n");
1750 fprintf(fd, "\n");
1751 fprintf(fd, "#ifdef CONFIG_LTT\n");
1752 fprintf(fd, "\n");
1753 fprintf(fd, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
1754 fprintf(fd, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
1755 fprintf(fd, "\n");
1756 fprintf(fd, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
1757 fprintf(fd, "\n");
1758 fprintf(fd, "#define SYMBOL_STRING(sym) #sym\n");
1759 fprintf(fd, "\n");
1760 fprintf(fd, "static struct ltt_facility facility = {\n");
1761 fprintf(fd, "\t.name = ltt_facility_name,\n");
1762 fprintf(fd, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
1763 fprintf(fd, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
1764 fprintf(fd, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
1765 fprintf(fd, "};\n");
1766 fprintf(fd, "\n");
1767 fprintf(fd, "#ifndef MODULE\n");
1768 fprintf(fd, "\n");
1769 fprintf(fd, "/* Built-in facility. */\n");
1770 fprintf(fd, "\n");
1771 fprintf(fd, "static int __init facility_init(void)\n");
1772 fprintf(fd, "{\n");
1773 fprintf(fd, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", fac->name);
1774 fprintf(fd, "\n");
1775 fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
1776 fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1777 fprintf(fd, "\t\n");
1778 fprintf(fd, "\treturn LTT_FACILITY_SYMBOL;\n");
1779 fprintf(fd, "}\n");
1780 fprintf(fd, "__initcall(facility_init);\n");
1781 fprintf(fd, "\n");
1782 fprintf(fd, "\n");
1783 fprintf(fd, "\n");
1784 fprintf(fd, "#else \n");
1785 fprintf(fd, "\n");
1786 fprintf(fd, "/* Dynamic facility. */\n");
1787 fprintf(fd, "\n");
1788 fprintf(fd, "static int __init facility_init(void)\n");
1789 fprintf(fd, "{\n");
1790 fprintf(fd, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", fac->name);
1791 fprintf(fd, "\n");
1792 fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1793 fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1794 fprintf(fd, "\n");
1795 fprintf(fd, "\treturn LTT_FACILITY_SYMBOL;\n");
1796 fprintf(fd, "}\n");
1797 fprintf(fd, "\n");
1798 fprintf(fd, "static void __exit facility_exit(void)\n");
1799 fprintf(fd, "{\n");
1800 fprintf(fd, "\tint err;\n");
1801 fprintf(fd, "\n");
1802 fprintf(fd, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1803 fprintf(fd, "\tif(err != 0)\n");
1804 fprintf(fd, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1805 fprintf(fd, "\n");
1806 fprintf(fd, "}\n");
1807 fprintf(fd, "\n");
1808 fprintf(fd, "module_init(facility_init)\n");
1809 fprintf(fd, "module_exit(facility_exit)\n");
1810 fprintf(fd, "\n");
1811 fprintf(fd, "\n");
1812 fprintf(fd, "MODULE_LICENSE(\"GPL\");\n");
1813 fprintf(fd, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1814 fprintf(fd, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1815 fprintf(fd, "\n");
1816 fprintf(fd, "#endif //MODULE\n");
1817 fprintf(fd, "\n");
1818 fprintf(fd, "#endif //CONFIG_LTT\n");
1819
1820 fclose(fd);
1821
1822 return 0;
1823 }
1824
1825
1826
1827 /* open facility */
1828 /* code taken from ltt_facility_open in ltt/facility.c in lttv */
1829
1830 /*****************************************************************************
1831 *Function name
1832 * ltt_facility_open : open facilities
1833 *Input params
1834 * pathname : the path name of the facility
1835 *
1836 * Open the facility corresponding to the right checksum.
1837 *
1838 *returns the facility on success, NULL on error.
1839 ****************************************************************************/
1840 facility_t *ltt_facility_open(char * pathname)
1841 {
1842 int ret = 0;
1843 char *token;
1844 parse_file_t in;
1845 facility_t * fac = NULL;
1846 char buffer[BUFFER_SIZE];
1847 int generated = FALSE;
1848
1849 in.buffer = &(buffer[0]);
1850 in.lineno = 0;
1851 in.error = error_callback;
1852 in.name = pathname;
1853 in.unget = 0;
1854
1855 in.fp = fopen(in.name, "r");
1856 if(in.fp == NULL) {
1857 ret = 1;
1858 goto open_error;
1859 }
1860
1861 while(1){
1862 token = getToken(&in);
1863 if(in.type == ENDFILE) break;
1864
1865 if(generated) {
1866 printf("More than one facility in the file. Only using the first one.\n");
1867 break;
1868 }
1869
1870 if(strcmp(token, "<")) in.error(&in,"not a facility file");
1871 token = getName(&in);
1872
1873 if(strcmp("facility",token) == 0) {
1874 fac = malloc(sizeof(facility_t));
1875 fac->name = NULL;
1876 fac->description = NULL;
1877 sequence_init(&(fac->events));
1878 table_init(&(fac->named_types));
1879 sequence_init(&(fac->unnamed_types));
1880
1881 parseFacility(&in, fac);
1882
1883 //check if any namedType is not defined
1884 checkNamedTypesImplemented(&fac->named_types);
1885
1886 generateChecksum(fac->name, &fac->checksum, &fac->events);
1887
1888 generated = TRUE;
1889 }
1890 else {
1891 printf("facility token was expected in file %s\n", in.name);
1892 ret = 1;
1893 goto parse_error;
1894 }
1895 }
1896
1897 parse_error:
1898 fclose(in.fp);
1899 open_error:
1900
1901 if(!generated) {
1902 printf("Cannot find facility %s\n", pathname);
1903 fac = NULL;
1904 }
1905
1906 return fac;
1907 }
1908
1909 /* Close the facility */
1910 void ltt_facility_close(facility_t *fac)
1911 {
1912 free(fac->name);
1913 free(fac->capname);
1914 free(fac->description);
1915 freeEvents(&fac->events);
1916 sequence_dispose(&fac->events);
1917 freeNamedType(&fac->named_types);
1918 table_dispose(&fac->named_types);
1919 freeTypes(&fac->unnamed_types);
1920 sequence_dispose(&fac->unnamed_types);
1921 free(fac);
1922 }
1923
1924
1925 /* Show help */
1926 void show_help(int argc, char ** argv)
1927 {
1928 printf("Genevent help : \n");
1929 printf("\n");
1930 printf("Use %s name.xml\n", argv[0]);
1931 printf("to create :\n");
1932 printf("ltt-facility-name.h\n");
1933 printf("ltt-facility-id-name.h\n");
1934 printf("ltt-facility-loader-name.h\n");
1935 printf("ltt-facility-loader-name.c\n");
1936 printf("In the current directory.\n");
1937 printf("\n");
1938 }
1939
1940 /* Parse program arguments */
1941 /* Return values :
1942 * 0 : continue program
1943 * -1 : stop program, return 0
1944 * > 0 : stop program, return value as exit.
1945 */
1946 int check_args(int argc, char **argv)
1947 {
1948 if(argc < 2) {
1949 printf("Not enough arguments\n");
1950 show_help(argc, argv);
1951 return EINVAL;
1952 }
1953
1954 if(strcmp(argv[1], "-h") == 0) {
1955 show_help(argc, argv);
1956 return -1;
1957 }
1958
1959 return 0;
1960 }
1961
1962 int main(int argc, char **argv)
1963 {
1964 int err = 0;
1965 facility_t *fac;
1966
1967 err = check_args(argc, argv);
1968 if(err > 0) return err;
1969 else if(err < 0) return 0;
1970
1971 /* open the facility */
1972 fac = ltt_facility_open(argv[1]);
1973 if(fac == NULL) {
1974 printf("Error opening file %s for reading : %s\n",
1975 argv[1], strerror(errno));
1976 return errno;
1977 }
1978
1979 /* generate the output C files */
1980
1981
1982 /* ltt-facility-name.h : main logging header.
1983 * log_header */
1984 err = print_log_header(fac);
1985 if(err) return err;
1986
1987 /* ltt-facility-id-name.h : facility id.
1988 * log_id_header */
1989 err = print_id_header(fac);
1990 if(err) return err;
1991
1992 /* ltt-facility-loader-name.h : facility specific loader info.
1993 * loader_header */
1994 err = print_loader_header(fac);
1995 if(err) return err;
1996
1997 /* ltt-facility-loader-name.c : generic faciilty loader
1998 * loader_c */
1999 err = print_loader_c(fac);
2000 if(err) return err;
2001
2002 /* close the facility */
2003 ltt_facility_close(fac);
2004
2005 return 0;
2006 }
2007
2008
This page took 0.095829 seconds and 4 git commands to generate.