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 | |
58 | #include <errno.h> |
59 | #include <sys/types.h> |
60 | #include <sys/stat.h> |
61 | #include <fcntl.h> |
62 | #include <stdio.h> |
63 | #include <string.h> |
64 | #include <unistd.h> |
65 | #include <stdlib.h> |
66 | |
67 | #include "genevent.h" |
68 | #include "parser.h" |
69 | |
70 | |
71 | #define TRUE 1 |
72 | #define FALSE (!TRUE) |
73 | |
74 | /* Code printing */ |
75 | |
76 | /* Type size checking */ |
77 | int print_check(int fd); |
78 | |
79 | |
80 | /* Print types */ |
81 | int print_types(int fd); |
82 | |
83 | |
84 | /* Print events */ |
85 | int print_events(int fd); |
86 | |
87 | |
88 | /* open facility */ |
89 | /* code taken from ltt_facility_open in ltt/facility.c in lttv */ |
90 | |
91 | /***************************************************************************** |
92 | *Function name |
93 | * ltt_facility_open : open facilities |
94 | *Input params |
95 | * pathname : the path name of the facility |
96 | * |
97 | * Open the facility corresponding to the right checksum. |
98 | * |
99 | *returns the facility on success, NULL on error. |
100 | ****************************************************************************/ |
101 | facility_t *ltt_facility_open(char * pathname) |
102 | { |
103 | int ret = 0; |
104 | char *token; |
105 | parse_file_t in; |
106 | facility_t * fac = NULL; |
107 | unsigned long checksum; |
108 | char buffer[BUFFER_SIZE]; |
109 | int generated = FALSE; |
110 | |
111 | in.buffer = &(buffer[0]); |
112 | in.lineno = 0; |
113 | in.error = error_callback; |
114 | in.name = pathname; |
115 | in.unget = 0; |
116 | |
117 | in.fp = fopen(in.name, "r"); |
118 | if(in.fp == NULL) { |
119 | ret = 1; |
120 | goto open_error; |
121 | } |
122 | |
123 | while(1){ |
124 | token = getToken(&in); |
125 | if(in.type == ENDFILE) break; |
126 | |
127 | if(generated) { |
128 | printf("More than one facility in the file. Only using the first one.\n"); |
129 | break; |
130 | } |
131 | |
132 | if(strcmp(token, "<")) in.error(&in,"not a facility file"); |
133 | token = getName(&in); |
134 | |
135 | if(strcmp("facility",token) == 0) { |
136 | fac = malloc(sizeof(facility_t)); |
137 | fac->name = NULL; |
138 | fac->description = NULL; |
139 | sequence_init(&(fac->events)); |
140 | table_init(&(fac->named_types)); |
141 | sequence_init(&(fac->unnamed_types)); |
142 | |
143 | parseFacility(&in, fac); |
144 | |
145 | //check if any namedType is not defined |
146 | checkNamedTypesImplemented(&fac->named_types); |
147 | |
148 | generateChecksum(fac->name, &checksum, &fac->events); |
149 | |
150 | generated = TRUE; |
151 | } |
152 | else { |
153 | printf("facility token was expected in file %s\n", in.name); |
154 | ret = 1; |
155 | goto parse_error; |
156 | } |
157 | } |
158 | |
159 | parse_error: |
160 | fclose(in.fp); |
161 | open_error: |
162 | |
163 | if(!generated) { |
164 | printf("Cannot find facility %s\n", pathname); |
165 | fac = NULL; |
166 | } |
167 | |
168 | return fac; |
169 | } |
170 | |
171 | /* Close the facility */ |
172 | void ltt_facility_close(facility_t *fac) |
173 | { |
174 | free(fac->name); |
175 | free(fac->capname); |
176 | free(fac->description); |
177 | freeEvents(&fac->events); |
178 | sequence_dispose(&fac->events); |
179 | freeNamedType(&fac->named_types); |
180 | table_dispose(&fac->named_types); |
181 | freeTypes(&fac->unnamed_types); |
182 | sequence_dispose(&fac->unnamed_types); |
183 | free(fac); |
184 | } |
185 | |
186 | |
187 | /* Show help */ |
188 | void show_help(int argc, char ** argv) |
189 | { |
190 | printf("Genevent help : \n"); |
191 | printf("\n"); |
192 | printf("Use %s name.xml\n", argv[0]); |
193 | printf("to create :\n"); |
194 | printf("ltt-facility-name.h\n"); |
195 | printf("ltt-facility-id-name.h\n"); |
196 | printf("ltt-facility-loader-name.h\n"); |
197 | printf("ltt-facility-loader-name.c\n"); |
198 | printf("In the current directory.\n"); |
199 | printf("\n"); |
200 | } |
201 | |
202 | /* Parse program arguments */ |
203 | /* Return values : |
204 | * 0 : continue program |
205 | * -1 : stop program, return 0 |
206 | * > 0 : stop program, return value as exit. |
207 | */ |
208 | int check_args(int argc, char **argv) |
209 | { |
210 | if(argc < 2) { |
211 | printf("Not enough arguments\n"); |
212 | show_help(argc, argv); |
213 | return EINVAL; |
214 | } |
215 | |
216 | if(strcmp(argv[1], "-h") == 0) { |
217 | show_help(argc, argv); |
218 | return -1; |
219 | } |
220 | |
221 | return 0; |
222 | } |
223 | |
224 | int main(int argc, char **argv) |
225 | { |
226 | int err = 0; |
227 | facility_t *fac; |
228 | |
229 | err = check_args(argc, argv); |
230 | if(err > 0) return err; |
231 | else if(err < 0) return 0; |
232 | |
233 | /* open the facility */ |
234 | fac = ltt_facility_open(argv[1]); |
235 | if(fac == NULL) { |
236 | printf("Error opening file %s for reading : %s\n", |
237 | argv[1], strerror(errno)); |
238 | return errno; |
239 | } |
240 | |
241 | /* generate the output C files */ |
242 | |
243 | |
244 | /* ltt-facility-name.h : main logging header */ |
245 | |
246 | |
247 | /* ltt-facility-id-name.h : facility id. */ |
248 | |
249 | |
250 | /* ltt-facility-loader-name.h : facility specific loader info. */ |
251 | |
252 | /* ltt-facility-loader-name.c : generic faciilty loader */ |
253 | |
254 | |
255 | |
256 | /* close the facility */ |
257 | ltt_facility_close(fac); |
258 | |
259 | return 0; |
260 | } |
261 | |
262 | |