sequence length type
[lttv.git] / genevent-new / 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
89
92d82357 90/* Code printing */
91
2d2d14a7 92void print_tabs(unsigned int tabs, FILE *fd)
93{
94 for(unsigned int i = 0; i<tabs;i++)
95 fprintf(fd, "\t");
96}
97
92d82357 98/* Type size checking */
2d2d14a7 99/* Uses #error in the generated code to signal error and stop the compiler */
92d82357 100int print_check(int fd);
101
102
2d2d14a7 103/* print type.
104 *
105 * Copied from construct_types_and_fields in LTTV facility.c */
106
107int print_type(type_descriptor_t * td, FILE *fd, unsigned int tabs,
108 char *nest_name, char *field_name)
109{
110 char basename[PATH_MAX];
111 unsigned int basename_len = 0;
112
113 strcpy(basename, nest_name);
114 basename_len = strlen(basename);
115
116 /* For a named type, we use the type_name directly */
117 if(td->type_name != NULL) {
118 strncpy(basename, td->type_name, PATH_MAX);
119 basename_len = strlen(basename);
120 } else {
121 /* For a unnamed type, there must be a field name */
7b175edc 122 if((basename_len != 0)
123 && (basename[basename_len-1] != '_')
124 && (field_name[0] != '\0')) {
2d2d14a7 125 strncat(basename, "_", PATH_MAX - basename_len);
126 basename_len = strlen(basename);
127 }
128 strncat(basename, field_name, PATH_MAX - basename_len);
129 }
130
131 switch(td->type) {
132 case INT_FIXED:
133 fprintf(fd, "%s", intOutputTypes[getSizeindex(td->size)]);
134 break;
135 case UINT_FIXED:
136 fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]);
137 break;
138 case CHAR:
139 fprintf(fd, "signed char");
140 break;
141 case UCHAR:
142 fprintf(fd, "unsigned char");
143 break;
144 case SHORT:
145 fprintf(fd, "short");
146 break;
147 case USHORT:
148 fprintf(fd, "unsigned short");
149 break;
150 case INT:
151 fprintf(fd, "int");
152 break;
153 case UINT:
154 fprintf(fd, "unsigned int");
155 break;
156 case FLOAT:
157 fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]);
158 break;
159 case POINTER:
160 fprintf(fd, "void *");
161 break;
162 case LONG:
163 fprintf(fd, "long");
164 break;
165 case ULONG:
166 fprintf(fd, "unsigned long");
167 break;
168 case SIZE_T:
169 fprintf(fd, "size_t");
170 break;
171 case SSIZE_T:
172 fprintf(fd, "ssize_t");
173 break;
174 case OFF_T:
175 fprintf(fd, "off_t");
176 break;
177 case STRING:
178 fprintf(fd, "char *");
179 break;
180 case ENUM:
181 fprintf(fd, "enum lttng_%s", basename);
182 break;
183 case ARRAY:
184 fprintf(fd, "lttng_array_%s", basename);
185 break;
186 case SEQUENCE:
187 fprintf(fd, "lttng_sequence_%s", basename);
188 break;
189 case STRUCT:
190 fprintf(fd, "struct lttng_%s", basename);
191 break;
192 case UNION:
193 fprintf(fd, "union lttng_%s", basename);
194 break;
195 default:
196 printf("print_type : unknown type\n");
197 return 1;
198 }
199
200 return 0;
201}
202
7e97b039 203/* Print logging function argument */
204int print_arg(type_descriptor_t * td, FILE *fd, unsigned int tabs,
205 char *nest_name, char *field_name)
206{
207 char basename[PATH_MAX];
208 unsigned int basename_len = 0;
209
210 strcpy(basename, nest_name);
211 basename_len = strlen(basename);
212
213 /* For a named type, we use the type_name directly */
214 if(td->type_name != NULL) {
215 strncpy(basename, td->type_name, PATH_MAX);
216 basename_len = strlen(basename);
217 } else {
218 /* For a unnamed type, there must be a field name */
219 if((basename_len != 0)
220 && (basename[basename_len-1] != '_')
221 && (field_name[0] != '\0')) {
222 strncat(basename, "_", PATH_MAX - basename_len);
223 basename_len = strlen(basename);
224 }
225 strncat(basename, field_name, PATH_MAX - basename_len);
226 }
227
228 print_tabs(tabs, fd);
229
230 switch(td->type) {
231 case INT_FIXED:
232 fprintf(fd, "%s", intOutputTypes[getSizeindex(td->size)]);
233 fprintf(fd, " %s", field_name);
234 break;
235 case UINT_FIXED:
236 fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]);
237 fprintf(fd, " %s", field_name);
238 break;
239 case CHAR:
240 fprintf(fd, "signed char");
241 fprintf(fd, " %s", field_name);
242 break;
243 case UCHAR:
244 fprintf(fd, "unsigned char");
245 fprintf(fd, " %s", field_name);
246 break;
247 case SHORT:
248 fprintf(fd, "short");
249 fprintf(fd, " %s", field_name);
250 break;
251 case USHORT:
252 fprintf(fd, "unsigned short");
253 fprintf(fd, " %s", field_name);
254 break;
255 case INT:
256 fprintf(fd, "int");
257 fprintf(fd, " %s", field_name);
258 break;
259 case UINT:
260 fprintf(fd, "unsigned int");
261 fprintf(fd, " %s", field_name);
262 break;
263 case FLOAT:
264 fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]);
265 fprintf(fd, " %s", field_name);
266 break;
267 case POINTER:
268 fprintf(fd, "void *");
269 fprintf(fd, " %s", field_name);
270 break;
271 case LONG:
272 fprintf(fd, "long");
273 fprintf(fd, " %s", field_name);
274 break;
275 case ULONG:
276 fprintf(fd, "unsigned long");
277 fprintf(fd, " %s", field_name);
278 break;
279 case SIZE_T:
280 fprintf(fd, "size_t");
281 fprintf(fd, " %s", field_name);
282 break;
283 case SSIZE_T:
284 fprintf(fd, "ssize_t");
285 fprintf(fd, " %s", field_name);
286 break;
287 case OFF_T:
288 fprintf(fd, "off_t");
289 fprintf(fd, " %s", field_name);
290 break;
291 case STRING:
292 fprintf(fd, "char *");
293 fprintf(fd, " %s", field_name);
294 break;
295 case ENUM:
296 fprintf(fd, "enum lttng_%s", basename);
297 fprintf(fd, " %s", field_name);
298 break;
299 case ARRAY:
300 fprintf(fd, "lttng_array_%s", basename);
301 fprintf(fd, " %s", field_name);
302 break;
303 case SEQUENCE:
304 fprintf(fd, "lttng_sequence_%s *", basename);
305 fprintf(fd, " %s", field_name);
306 break;
307 case STRUCT:
308 fprintf(fd, "struct lttng_%s *", basename);
309 fprintf(fd, " %s", field_name);
310 break;
311 case UNION:
312 fprintf(fd, "union lttng_%s *", basename);
313 fprintf(fd, " %s", field_name);
314 break;
315 default:
316 printf("print_type : unknown type\n");
317 return 1;
318 }
319
320 return 0;
321}
322
323
2d2d14a7 324/* print type declaration.
325 *
326 * Copied from construct_types_and_fields in LTTV facility.c */
327
328int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs,
329 char *nest_name, char *field_name)
330{
331 char basename[PATH_MAX];
332 unsigned int basename_len = 0;
333
7b175edc 334 strncpy(basename, nest_name, PATH_MAX);
2d2d14a7 335 basename_len = strlen(basename);
336
337 /* For a named type, we use the type_name directly */
338 if(td->type_name != NULL) {
339 strncpy(basename, td->type_name, PATH_MAX);
340 basename_len = strlen(basename);
341 } else {
7b175edc 342 /* For a unnamed type, there must be a field name, except for
343 * the array. */
344 if((basename_len != 0)
345 && (basename[basename_len-1] != '_'
346 && (field_name[0] != '\0'))) {
2d2d14a7 347 strncat(basename, "_", PATH_MAX - basename_len);
348 basename_len = strlen(basename);
349 }
350 strncat(basename, field_name, PATH_MAX - basename_len);
2d2d14a7 351 }
352
353 switch(td->type) {
354 case ENUM:
355 fprintf(fd, "enum lttng_%s", basename);
356 fprintf(fd, " {\n");
357 for(unsigned int i=0;i<td->labels.position;i++){
358 print_tabs(1, fd);
359 fprintf(fd, "LTTNG_%s", ((char*)(td->labels.array[i])));
360 fprintf(fd, ",\n");
361 }
362 fprintf(fd, "};\n");
363 fprintf(fd, "\n");
364 break;
365
366 case ARRAY:
7b175edc 367 dprintf("%s\n", basename);
2d2d14a7 368 assert(td->size >= 0);
369 if(td->nested_type->type_name == NULL) {
370 /* Not a named nested type : we must print its declaration first */
371 if(print_type_declaration(td->nested_type,
372 fd, 0, basename, "")) return 1;
373 }
374 fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename,
375 td->size);
7e97b039 376 fprintf(fd, "typedef ");
47299663 377 if(print_type(td->nested_type, fd, tabs, basename, "")) return 1;
2d2d14a7 378 fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename,
379 basename);
380 fprintf(fd, "\n");
381 break;
382 case SEQUENCE:
383 if(td->nested_type->type_name == NULL) {
384 /* Not a named nested type : we must print its declaration first */
385 if(print_type_declaration(td->nested_type,
386 fd, 0, basename, "")) return 1;
387 }
388 fprintf(fd, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n",
389 basename,
390 basename);
391 fprintf(fd, "struct lttng_sequence_%s", basename);
392 fprintf(fd, " {\n");
393 print_tabs(1, fd);
394 fprintf(fd, "unsigned int len;\n");
395 print_tabs(1, fd);
47299663 396 if(print_type(td->nested_type, fd, tabs, basename, "")) return 1;
2d2d14a7 397 fprintf(fd, " *array;\n");
398 fprintf(fd, "};\n");
399 fprintf(fd, "\n");
400 break;
401
402 case STRUCT:
403 for(unsigned int i=0;i<td->fields.position;i++){
404 field_t *field = (field_t*)(td->fields.array[i]);
405 type_descriptor_t *type = field->type;
406 if(type->type_name == NULL) {
407 /* Not a named nested type : we must print its declaration first */
408 if(print_type_declaration(type,
409 fd, 0, basename, field->name)) return 1;
410 }
411 }
412 fprintf(fd, "struct lttng_%s", basename);
413 fprintf(fd, " {\n");
414 for(unsigned int i=0;i<td->fields.position;i++){
415 field_t *field = (field_t*)(td->fields.array[i]);
416 type_descriptor_t *type = field->type;
417 print_tabs(1, fd);
47299663 418 if(print_type(type, fd, tabs, basename, field->name)) return 1;
2d2d14a7 419 fprintf(fd, " ");
420 fprintf(fd, "%s", field->name);
421 fprintf(fd, ";\n");
422 }
423 fprintf(fd, "};\n");
424 fprintf(fd, "\n");
425 break;
426 case UNION:
427 /* TODO : Do not allow variable length fields in a union */
428 for(unsigned int i=0;i<td->fields.position;i++){
429 field_t *field = (field_t*)(td->fields.array[i]);
430 type_descriptor_t *type = field->type;
431 if(type->type_name == NULL) {
432 /* Not a named nested type : we must print its declaration first */
47299663 433 if(print_type_declaration(type,
434 fd, 0, basename, field->name)) return 1;
2d2d14a7 435 }
436 }
437 fprintf(fd, "union lttng_%s", basename);
438 fprintf(fd, " {\n");
439 for(unsigned i=0;i<td->fields.position;i++){
440 field_t *field = (field_t*)(td->fields.array[i]);
441 type_descriptor_t *type = field->type;
442 print_tabs(1, fd);
47299663 443 if(print_type(type, fd, tabs, basename, field->name)) return 1;
2d2d14a7 444 fprintf(fd, " ");
445 fprintf(fd, "%s", field->name);
446 fprintf(fd, ";\n");
447 }
448 fprintf(fd, "};\n");
449 fprintf(fd, "\n");
450 break;
451 default:
452 dprintf("print_type_declaration : unknown type or nothing to declare.\n");
453 break;
454 }
455
456 return 0;
457}
458
47299663 459/* Print the logging function of an event. This is the core of genevent */
460int print_event_logging_function(char *basename, event_t *event, FILE *fd)
461{
462 fprintf(fd, "static inline void trace_%s(\n", basename);
463 for(unsigned int j = 0; j < event->fields.position; j++) {
464 /* For each field, print the function argument */
465 field_t *f = (field_t*)event->fields.array[j];
466 type_descriptor_t *t = f->type;
7e97b039 467 if(print_arg(t, fd, 2, basename, f->name)) return 1;
47299663 468 if(j < event->fields.position-1) {
469 fprintf(fd, ",");
470 fprintf(fd, "\n");
471 }
472 }
473 if(event->fields.position == 0) {
474 print_tabs(2, fd);
475 fprintf(fd, "void");
476 }
477 fprintf(fd,")\n");
478 fprintf(fd, "#ifndef CONFIG_LTT\n");
479 fprintf(fd, "{\n");
480 fprintf(fd, "}\n");
481 fprintf(fd,"#else\n");
482 fprintf(fd, "{\n");
7e97b039 483 /* Print the function variables */
484
485 /* Calculate event variable len + event alignment offset.
486 * Assume that the padding for alignment starts at a void*
487 * address. */
47299663 488
7e97b039 489 /* Take locks : make sure the trace does not vanish while we write on
490 * it. A simple preemption disabling is enough (using rcu traces). */
491
492 /* For each trace */
493
494 /* Relay reserve */
495 /* If error, increment counter and return */
496
497 /* write data */
498
499 /* commit */
500
501 /* Release locks */
2d2d14a7 502
47299663 503 fprintf(fd, "}\n");
504 fprintf(fd, "#endif //CONFIG_LTT\n\n");
505 return 0;
506}
2d2d14a7 507
508
509/* ltt-facility-name.h : main logging header.
510 * log_header */
511
512void print_log_header_head(facility_t *fac, FILE *fd)
513{
514 fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
515 fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
47299663 516 fprintf(fd, "\n");
517 fprintf(fd, "/* Facility activation at compile time. */\n");
518 fprintf(fd, "#ifdef CONFIG_LTT_FACILITY_%s\n\n", fac->capname);
2d2d14a7 519}
520
521
522
2d2d14a7 523int print_log_header_types(facility_t *fac, FILE *fd)
524{
525 sequence_t *types = &fac->named_types.values;
526 fprintf(fd, "/* Named types */\n");
527 fprintf(fd, "\n");
528
529 for(unsigned int i = 0; i < types->position; i++) {
530 /* For each named type, print the definition */
531 if((print_type_declaration(types->array[i], fd,
532 0, "", ""))) return 1;
533 }
534 return 0;
535}
536
537int print_log_header_events(facility_t *fac, FILE *fd)
538{
47299663 539 sequence_t *events = &fac->events;
540 char basename[PATH_MAX];
541 unsigned int facname_len;
542
543 strncpy(basename, fac->name, PATH_MAX);
544 facname_len = strlen(basename);
545 strncat(basename, "_", PATH_MAX-facname_len);
546 facname_len = strlen(basename);
547
548 for(unsigned int i = 0; i < events->position; i++) {
549 event_t *event = (event_t*)events->array[i];
550 strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
551
552 /* For each event, print structure, and then logging function */
553 fprintf(fd, "/* Event %s structures */\n",
554 event->name);
555 for(unsigned int j = 0; j < event->fields.position; j++) {
556 /* For each unnamed type, print the definition */
557 field_t *f = (field_t*)event->fields.array[j];
558 type_descriptor_t *t = f->type;
559 if(t->type_name == NULL)
560 if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
561 }
562 fprintf(fd, "\n");
2d2d14a7 563
47299663 564 fprintf(fd, "/* Event %s logging function */\n",
565 event->name);
566
567 if(print_event_logging_function(basename, event, fd)) return 1;
568
569 fprintf(fd, "\n");
570 }
571
2d2d14a7 572 return 0;
573}
574
575
576void print_log_header_tail(facility_t *fac, FILE *fd)
577{
47299663 578 fprintf(fd, "#endif //CONFIG_LTT_FACILITY_%s\n\n", fac->capname);
2d2d14a7 579 fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
580}
581
582int print_log_header(facility_t *fac)
583{
584 char filename[PATH_MAX];
585 unsigned int filename_size = 0;
586 FILE *fd;
587 dprintf("%s\n", fac->name);
588
589 strcpy(filename, "ltt-facility-");
590 filename_size = strlen(filename);
591
592 strncat(filename, fac->name, PATH_MAX - filename_size);
593 filename_size = strlen(filename);
594
595 strncat(filename, ".h", PATH_MAX - filename_size);
596 filename_size = strlen(filename);
597
598
599 fd = fopen(filename, "w");
600 if(fd == NULL) {
601 printf("Error opening file %s for writing : %s\n",
602 filename, strerror(errno));
603 return errno;
604 }
605
606 /* Print file head */
607 print_log_header_head(fac, fd);
608
609 /* print named types in declaration order */
610 if(print_log_header_types(fac, fd)) return 1;
611
612 /* Print events */
613 if(print_log_header_events(fac, fd)) return 1;
614
615 /* Print file tail */
616 print_log_header_tail(fac, fd);
617
618
619 fclose(fd);
620
621 return 0;
622}
623
624
625/* ltt-facility-id-name.h : facility id.
626 * log_id_header */
627int print_id_header(facility_t *fac)
628{
629 char filename[PATH_MAX];
630 unsigned int filename_size = 0;
631 FILE *fd;
632 dprintf("%s\n", fac->name);
633
634 strcpy(filename, "ltt-facility-id-");
635 filename_size = strlen(filename);
636
637 strncat(filename, fac->name, PATH_MAX - filename_size);
638 filename_size = strlen(filename);
639
640 strncat(filename, ".h", PATH_MAX - filename_size);
641 filename_size = strlen(filename);
642
643
644 fd = fopen(filename, "w");
645 if(fd == NULL) {
646 printf("Error opening file %s for writing : %s\n",
647 filename, strerror(errno));
648 return errno;
649 }
650
651 fclose(fd);
652
653 return 0;
654}
655
656
657/* ltt-facility-loader-name.h : facility specific loader info.
658 * loader_header */
659int print_loader_header(facility_t *fac)
660{
661 char filename[PATH_MAX];
662 unsigned int filename_size = 0;
663 FILE *fd;
664 dprintf("%s\n", fac->name);
665
666 strcpy(filename, "ltt-facility-loader-");
667 filename_size = strlen(filename);
668
669 strncat(filename, fac->name, PATH_MAX - filename_size);
670 filename_size = strlen(filename);
671
672 strncat(filename, ".h", PATH_MAX - filename_size);
673 filename_size = strlen(filename);
674
675
676 fd = fopen(filename, "w");
677 if(fd == NULL) {
678 printf("Error opening file %s for writing : %s\n",
679 filename, strerror(errno));
680 return errno;
681 }
682
683 fclose(fd);
684
685 return 0;
686}
687
688/* ltt-facility-loader-name.c : generic faciilty loader
689 * loader_c */
690int print_loader_c(facility_t *fac)
691{
692 char filename[PATH_MAX];
693 unsigned int filename_size = 0;
694 FILE *fd;
695 dprintf("%s\n", fac->name);
696
697 strcpy(filename, "ltt-facility-loader-");
698 filename_size = strlen(filename);
699
700 strncat(filename, fac->name, PATH_MAX - filename_size);
701 filename_size = strlen(filename);
702
703 strncat(filename, ".c", PATH_MAX - filename_size);
704 filename_size = strlen(filename);
705
706
707 fd = fopen(filename, "w");
708 if(fd == NULL) {
709 printf("Error opening file %s for writing : %s\n",
710 filename, strerror(errno));
711 return errno;
712 }
713
714
715 fclose(fd);
716
717 return 0;
718}
719
720
721
92d82357 722/* open facility */
723/* code taken from ltt_facility_open in ltt/facility.c in lttv */
724
725/*****************************************************************************
726 *Function name
727 * ltt_facility_open : open facilities
728 *Input params
729 * pathname : the path name of the facility
730 *
731 * Open the facility corresponding to the right checksum.
732 *
733 *returns the facility on success, NULL on error.
734 ****************************************************************************/
735facility_t *ltt_facility_open(char * pathname)
736{
737 int ret = 0;
738 char *token;
739 parse_file_t in;
740 facility_t * fac = NULL;
741 unsigned long checksum;
742 char buffer[BUFFER_SIZE];
743 int generated = FALSE;
744
745 in.buffer = &(buffer[0]);
746 in.lineno = 0;
747 in.error = error_callback;
748 in.name = pathname;
749 in.unget = 0;
750
751 in.fp = fopen(in.name, "r");
752 if(in.fp == NULL) {
753 ret = 1;
754 goto open_error;
755 }
756
757 while(1){
758 token = getToken(&in);
759 if(in.type == ENDFILE) break;
760
761 if(generated) {
762 printf("More than one facility in the file. Only using the first one.\n");
763 break;
764 }
765
766 if(strcmp(token, "<")) in.error(&in,"not a facility file");
767 token = getName(&in);
768
769 if(strcmp("facility",token) == 0) {
770 fac = malloc(sizeof(facility_t));
771 fac->name = NULL;
772 fac->description = NULL;
773 sequence_init(&(fac->events));
774 table_init(&(fac->named_types));
775 sequence_init(&(fac->unnamed_types));
776
777 parseFacility(&in, fac);
778
779 //check if any namedType is not defined
780 checkNamedTypesImplemented(&fac->named_types);
781
782 generateChecksum(fac->name, &checksum, &fac->events);
783
784 generated = TRUE;
785 }
786 else {
787 printf("facility token was expected in file %s\n", in.name);
788 ret = 1;
789 goto parse_error;
790 }
791 }
792
793 parse_error:
794 fclose(in.fp);
795open_error:
796
797 if(!generated) {
798 printf("Cannot find facility %s\n", pathname);
799 fac = NULL;
800 }
801
802 return fac;
803}
804
805/* Close the facility */
806void ltt_facility_close(facility_t *fac)
807{
808 free(fac->name);
809 free(fac->capname);
810 free(fac->description);
811 freeEvents(&fac->events);
812 sequence_dispose(&fac->events);
813 freeNamedType(&fac->named_types);
814 table_dispose(&fac->named_types);
815 freeTypes(&fac->unnamed_types);
816 sequence_dispose(&fac->unnamed_types);
817 free(fac);
818}
819
820
821/* Show help */
822void show_help(int argc, char ** argv)
823{
824 printf("Genevent help : \n");
825 printf("\n");
826 printf("Use %s name.xml\n", argv[0]);
827 printf("to create :\n");
828 printf("ltt-facility-name.h\n");
829 printf("ltt-facility-id-name.h\n");
830 printf("ltt-facility-loader-name.h\n");
831 printf("ltt-facility-loader-name.c\n");
832 printf("In the current directory.\n");
833 printf("\n");
834}
835
836/* Parse program arguments */
837/* Return values :
838 * 0 : continue program
839 * -1 : stop program, return 0
840 * > 0 : stop program, return value as exit.
841 */
842int check_args(int argc, char **argv)
843{
844 if(argc < 2) {
845 printf("Not enough arguments\n");
846 show_help(argc, argv);
847 return EINVAL;
848 }
849
850 if(strcmp(argv[1], "-h") == 0) {
851 show_help(argc, argv);
852 return -1;
853 }
854
855 return 0;
856}
857
858int main(int argc, char **argv)
859{
860 int err = 0;
861 facility_t *fac;
862
863 err = check_args(argc, argv);
864 if(err > 0) return err;
865 else if(err < 0) return 0;
866
867 /* open the facility */
868 fac = ltt_facility_open(argv[1]);
869 if(fac == NULL) {
870 printf("Error opening file %s for reading : %s\n",
871 argv[1], strerror(errno));
872 return errno;
873 }
874
875 /* generate the output C files */
876
877
2d2d14a7 878 /* ltt-facility-name.h : main logging header.
879 * log_header */
880 err = print_log_header(fac);
881 if(err) return err;
92d82357 882
2d2d14a7 883 /* ltt-facility-id-name.h : facility id.
884 * log_id_header */
885 err = print_id_header(fac);
886 if(err) return err;
92d82357 887
2d2d14a7 888 /* ltt-facility-loader-name.h : facility specific loader info.
889 * loader_header */
890 err = print_loader_header(fac);
891 if(err) return err;
892
893 /* ltt-facility-loader-name.c : generic faciilty loader
894 * loader_c */
895 err = print_loader_c(fac);
896 if(err) return err;
92d82357 897
898 /* close the facility */
899 ltt_facility_close(fac);
900
901 return 0;
902}
903
904
This page took 0.057066 seconds and 4 git commands to generate.