e8548639 |
1 | |
449cb9d7 |
2 | /* This file is part of the Linux Trace Toolkit viewer |
3 | * Copyright (C) 2003-2004 Xiangxiu Yang |
3aee1200 |
4 | * 2005 Mathieu Desnoyers |
449cb9d7 |
5 | * |
1b44b0b5 |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License Version 2.1 as published by the Free Software Foundation. |
449cb9d7 |
9 | * |
1b44b0b5 |
10 | * This library is distributed in the hope that it will be useful, |
449cb9d7 |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1b44b0b5 |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
449cb9d7 |
14 | * |
1b44b0b5 |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. |
449cb9d7 |
19 | */ |
20 | |
4e4d11b3 |
21 | #ifdef HAVE_CONFIG_H |
22 | #include <config.h> |
23 | #endif |
24 | |
6cd62ccf |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | #include <stdio.h> |
cdf90f40 |
28 | #include <glib.h> |
45e14832 |
29 | #include <sys/types.h> |
30 | #include <sys/stat.h> |
31 | #include <fcntl.h> |
32 | |
33 | |
6cd62ccf |
34 | |
6cd62ccf |
35 | #include "parser.h" |
a5dcde2f |
36 | #include <ltt/ltt.h> |
37 | #include "ltt-private.h" |
6cd62ccf |
38 | #include <ltt/facility.h> |
39 | |
86005ded |
40 | #ifndef g_open |
41 | #define g_open open |
42 | #endif |
43 | |
45e14832 |
44 | #define g_close close |
45 | |
6cd62ccf |
46 | /* search for the (named) type in the table, if it does not exist |
47 | create a new one */ |
90699b2b |
48 | LttType * lookup_named_type(LttFacility *fac, type_descriptor_t * td); |
6cd62ccf |
49 | |
50 | /* construct directed acyclic graph for types, and tree for fields */ |
2312de30 |
51 | void construct_fields(LttFacility *fac, |
c1161b10 |
52 | LttField *field, |
2312de30 |
53 | field_t *fld); |
6cd62ccf |
54 | |
55 | /* generate the facility according to the events belongin to it */ |
8d1e6362 |
56 | void generateFacility(LttFacility * f, facility_t * fac, |
3aee1200 |
57 | guint32 checksum); |
6cd62ccf |
58 | |
59 | /* functions to release the memory occupied by a facility */ |
963b5f2d |
60 | void freeFacility(LttFacility * facility); |
61 | void freeEventtype(LttEventType * evType); |
2312de30 |
62 | void freeLttType(LttType * type); |
963b5f2d |
63 | void freeLttField(LttField * fld); |
908f42fa |
64 | void freeLttNamedType(LttType * type); |
6cd62ccf |
65 | |
66 | |
e8548639 |
67 | /***************************************************************************** |
68 | *Function name |
69 | * parse_fmt : parses the format string |
70 | *Input params |
71 | * fmt : format string specified in the xml file |
72 | * header : points to the extracted header string |
73 | * separator : points to the extracted separator string |
74 | * footer : points to the extracted footer string |
75 | * |
76 | * Parses the format string in order to extract the header, |
77 | * the separator and the footer. |
78 | * The default fmt string is: { %S, %S } |
79 | * In this case: |
80 | * The header is: { |
81 | * The separator is: , |
82 | * The footer |
83 | * |
84 | ****************************************************************************/ |
85 | |
86 | parse_fmt(char *fmt, char **header, char **separator, char **footer){ |
87 | int i; |
88 | unsigned int num = 0; |
89 | |
90 | int header_index = 0;//header index |
91 | int separator_index = 0;//separator index |
92 | int footer_index = 0;//footer index |
93 | int fmt_length = strlen(fmt); |
94 | |
95 | for(i=0; i<fmt_length; i++) |
96 | { |
97 | if(fmt[i]=='%') |
98 | { |
99 | num++; |
100 | if(num>=3) |
101 | g_error("More than 2 '%%' chars were encountered: %s\n",fmt); |
102 | |
103 | //Detecting identifier |
104 | if(fmt[++i]!='S') |
105 | g_error("Unexpected format: %s\n",fmt); |
106 | |
107 | if(i+1<strlen(fmt)) |
108 | i = i+1; |
109 | else |
110 | g_error("Unexpected format: %s\n",fmt); |
111 | |
112 | //Need to have at least on char after the %S |
113 | if(fmt[i]=='%') |
114 | g_error("Missing separator: %s\n",fmt); |
115 | |
116 | if(separator_index==0) |
117 | separator_index = i;//index of separator inside the original string. |
118 | else if(footer_index==0)//the 'else' gives the priority to set the separator index first. |
119 | footer_index = i;//no break since an error should be generated if more than 2 '%' were encountered |
120 | } |
121 | } |
122 | |
123 | |
124 | //Create header String |
125 | num = separator_index-header_index-2;//(-2 due to '%S') |
126 | if(num<0) |
127 | g_error("Unexpected format"); |
128 | //*header = malloc(num+1);//(+1 for EOS). |
129 | *header = g_new(gchar,num+1);//(+1 for EOS). |
130 | strncpy(*header,fmt,num); |
131 | (*header)[num] = '\0';//need EOS, not handled by strncopy |
132 | |
133 | //Create seperator String |
134 | num =footer_index - separator_index - 2; |
135 | if(num<0) |
136 | g_error("Unexpected format"); |
137 | //*separator = malloc(num+1);//+1 for EOS |
138 | *separator = g_new(gchar, num+1);//+1 for EOS |
139 | strncpy(*separator,fmt+separator_index*sizeof(char),num); |
140 | (*separator)[num] = '\0';//need EOS, not handled by strncopy |
141 | |
142 | //Create footer String |
143 | num = strlen(fmt)-footer_index; |
144 | //*footer = malloc(num+1); |
145 | *footer = g_new(gchar, num+1); |
146 | strncpy(*footer,fmt+footer_index*sizeof(char),num); |
147 | (*footer)[num] = '\0'; |
148 | } |
149 | |
150 | /***************************************************************************** |
151 | *Function name |
152 | * verify_fmt_syntax : verifies the syntax of the format string |
153 | *Input params |
154 | * fmt : format string specified in the xml file |
155 | * fmt_type : points to the detected type in the fmt string |
156 | * |
157 | * Verifies the syntax of the format string sepcified in the xml file |
158 | * It allows fmt strings having the following syntax: |
159 | * "..header text... %12.20d ...footer text..." |
160 | * It sets the fmt_type accordingly. In the previous example |
161 | * fmt_type would point to the character 'd' inside fmt. |
162 | * |
163 | *returns 1 on success, and -1 or -2 on error. |
164 | * |
165 | ****************************************************************************/ |
166 | |
167 | int verify_fmt_syntax(char *fmt, char **fmt_type){ |
168 | int i; |
169 | int dot = 0;//number of dots encountered. |
170 | unsigned short counter = 0; |
171 | *fmt_type=NULL; |
172 | |
173 | |
174 | for(i=0; i<strlen(fmt); i++) |
175 | { |
176 | if(fmt[i]=='%') |
177 | { |
178 | if(++counter==2) |
179 | return -1;//should generate an error. |
180 | |
181 | i = i+1;//go to next character |
182 | |
183 | if(fmt[i]=='-' && i<(strlen(fmt)-1)) |
184 | i++;//allow this character after the '%' |
185 | |
186 | if(fmt[i]=='#' && i<(strlen(fmt)-1)) |
187 | i++;//allow this character |
188 | } |
189 | |
190 | if(counter ==1 && !isdigit(fmt[i]) && *fmt_type==NULL) |
191 | switch (fmt[i]){ |
192 | case 'd': |
193 | case 'i': |
194 | case 'u': |
195 | case 'o': |
196 | case 'x': |
197 | case 'X': |
198 | case 'f': |
199 | case 'e': |
200 | case 'E': |
201 | case 's': |
202 | case 'p': |
203 | *fmt_type=&fmt[i]; |
204 | break; |
205 | //do not return yet. may encounter another '%' |
206 | case '.': |
207 | if(++dot==2) |
208 | return -2;//generate error |
209 | break; |
210 | default: |
211 | return -1; |
212 | } |
213 | |
214 | } |
215 | |
216 | return 1; |
217 | |
218 | } |
219 | |
220 | /***************************************************************************** |
221 | *Function name |
222 | * append_ll : appends "ll" to the format string |
223 | *Input params |
224 | * fmt : format string specified in the xml file |
225 | * fmt_type : address of the format char inside fmt |
226 | * |
227 | * inserts "ll" just before the fmt_type |
228 | * |
229 | ****************************************************************************/ |
230 | |
231 | void append_ll (char **fmt, char **fmt_type){ |
232 | char *new_fmt; |
233 | int i; |
234 | int num; |
235 | |
236 | |
f6e3111c |
237 | //the +2 corresponds the the "ll"; the +1 is the \0 |
238 | new_fmt = g_new(gchar, strlen(*fmt)+2+1); |
e8548639 |
239 | |
240 | num = *fmt_type - *fmt; |
241 | |
242 | for(i=0; i<num;i++) |
243 | new_fmt[i] =(*fmt)[i]; |
244 | |
245 | new_fmt[i++] = 'l'; |
246 | new_fmt[i++] = 'l'; |
247 | |
248 | |
249 | while(i-2<strlen(*fmt)) |
250 | { |
251 | new_fmt[i]=(*fmt)[i-2]; |
252 | i++; |
253 | } |
254 | |
255 | *fmt = new_fmt; |
256 | (*fmt)[i] = '\0'; |
257 | |
258 | } |
259 | |
260 | |
6cd62ccf |
261 | /***************************************************************************** |
262 | *Function name |
963b5f2d |
263 | * ltt_facility_open : open facilities |
6cd62ccf |
264 | *Input params |
963b5f2d |
265 | * t : the trace containing the facilities |
6cd62ccf |
266 | * pathname : the path name of the facility |
3aee1200 |
267 | * |
29e7c5b3 |
268 | * Open the facility corresponding to the right checksum. |
269 | * |
3aee1200 |
270 | *returns 0 on success, 1 on error. |
6cd62ccf |
271 | ****************************************************************************/ |
272 | |
3aee1200 |
273 | int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname) |
6cd62ccf |
274 | { |
a0c1f622 |
275 | int ret = 0; |
45e14832 |
276 | gchar *token; |
90699b2b |
277 | parse_file_t in; |
8d1e6362 |
278 | facility_t * fac; |
2312de30 |
279 | unsigned int checksum; |
45e14832 |
280 | gchar buffer[BUFFER_SIZE]; |
29e7c5b3 |
281 | gboolean generated = FALSE; |
6cd62ccf |
282 | |
45e14832 |
283 | in.buffer = &(buffer[0]); |
6cd62ccf |
284 | in.lineno = 0; |
285 | in.error = error_callback; |
963b5f2d |
286 | in.name = pathname; |
ba8a51cd |
287 | in.unget = 0; |
6cd62ccf |
288 | |
90699b2b |
289 | in.fp = fopen(in.name, "r"); |
cb03932a |
290 | if(in.fp == NULL) { |
3aee1200 |
291 | g_warning("cannot open facility description file %s", |
292 | in.name); |
a0c1f622 |
293 | ret = 1; |
294 | goto open_error; |
3aee1200 |
295 | } |
45e14832 |
296 | |
6cd62ccf |
297 | while(1){ |
298 | token = getToken(&in); |
299 | if(in.type == ENDFILE) break; |
e6d018d4 |
300 | |
c1161b10 |
301 | if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file"); |
302 | token = getName(&in); |
303 | if(g_ascii_strcasecmp(token, "?")) in.error(&in,"not a facility file"); |
304 | token = getName(&in); |
305 | if(g_ascii_strcasecmp(token, "xml")) in.error(&in,"not a facility file"); |
306 | token = getName(&in); |
307 | if(g_ascii_strcasecmp(token, "version")) in.error(&in,"not a facility file"); |
308 | token = getName(&in); |
309 | if(g_ascii_strcasecmp(token, "=")) in.error(&in,"not a facility file"); |
310 | token = getQuotedString(&in); |
311 | if(g_ascii_strcasecmp(token, "1.0")) in.error(&in,"not a facility file"); |
312 | token = getName(&in); |
313 | if(g_ascii_strcasecmp(token, "?")) in.error(&in,"not a facility file"); |
314 | token = getToken(&in); |
315 | if(g_ascii_strcasecmp(token, ">")) in.error(&in,"not a facility file"); |
316 | |
317 | token = getToken(&in); |
318 | |
45e14832 |
319 | if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file"); |
963b5f2d |
320 | token = getName(&in); |
45e14832 |
321 | |
322 | if(g_ascii_strcasecmp("facility",token) == 0) { |
8d1e6362 |
323 | fac = g_new(facility_t, 1); |
963b5f2d |
324 | fac->name = NULL; |
325 | fac->description = NULL; |
326 | sequence_init(&(fac->events)); |
327 | table_init(&(fac->named_types)); |
328 | sequence_init(&(fac->unnamed_types)); |
329 | |
330 | parseFacility(&in, fac); |
331 | |
332 | //check if any namedType is not defined |
90699b2b |
333 | checkNamedTypesImplemented(&fac->named_types); |
963b5f2d |
334 | |
90699b2b |
335 | generateChecksum(fac->name, &checksum, &fac->events); |
cba098f3 |
336 | // FIXME if(checksum == f->checksum) { |
29e7c5b3 |
337 | generateFacility(f, fac, checksum); |
338 | generated = TRUE; |
cba098f3 |
339 | //} |
340 | if (checksum != f->checksum) |
341 | g_warning("Facility checksum mismatch for facility %s : kernel 0x%X vs " |
342 | "XML 0x%X\n", fac->name, f->checksum, checksum); |
963b5f2d |
343 | |
45e14832 |
344 | g_free(fac->name); |
d2ace3a9 |
345 | free(fac->capname); |
45e14832 |
346 | g_free(fac->description); |
963b5f2d |
347 | freeEvents(&fac->events); |
348 | sequence_dispose(&fac->events); |
349 | freeNamedType(&fac->named_types); |
350 | table_dispose(&fac->named_types); |
351 | freeTypes(&fac->unnamed_types); |
352 | sequence_dispose(&fac->unnamed_types); |
cf1307af |
353 | g_free(fac); |
129fd24a |
354 | if(generated) break; /* use the first good match */ |
6cd62ccf |
355 | } |
3aee1200 |
356 | else { |
357 | g_warning("facility token was expected in file %s", in.name); |
a0c1f622 |
358 | ret = 1; |
3aee1200 |
359 | goto parse_error; |
360 | } |
6cd62ccf |
361 | } |
29e7c5b3 |
362 | |
3aee1200 |
363 | parse_error: |
90699b2b |
364 | fclose(in.fp); |
a0c1f622 |
365 | open_error: |
90699b2b |
366 | |
986e2a7c |
367 | if(!generated) { |
368 | g_warning("Cannot find facility %s, checksum 0x%X", |
369 | g_quark_to_string(f->name), f->checksum); |
370 | ret = 1; |
371 | } |
29e7c5b3 |
372 | |
a0c1f622 |
373 | return ret; |
6cd62ccf |
374 | } |
375 | |
376 | |
377 | /***************************************************************************** |
378 | *Function name |
379 | * generateFacility : generate facility, internal function |
380 | *Input params |
963b5f2d |
381 | * facility : LttFacilty structure |
382 | * fac : facility structure |
6cd62ccf |
383 | * checksum : checksum of the facility |
6cd62ccf |
384 | ****************************************************************************/ |
385 | |
3aee1200 |
386 | void generateFacility(LttFacility *f, facility_t *fac, guint32 checksum) |
6cd62ccf |
387 | { |
963b5f2d |
388 | char * facilityName = fac->name; |
90699b2b |
389 | sequence_t * events = &fac->events; |
f104d082 |
390 | unsigned int i, j; |
963b5f2d |
391 | LttType * type; |
f104d082 |
392 | table_t *named_types = &fac->named_types; |
6cd62ccf |
393 | |
3aee1200 |
394 | g_assert(f->name == g_quark_from_string(facilityName)); |
cba098f3 |
395 | //g_assert(f->checksum == checksum); |
3aee1200 |
396 | |
397 | //f->event_number = events->position; |
6cd62ccf |
398 | |
399 | //initialize inner structures |
3aee1200 |
400 | f->events = g_array_sized_new (FALSE, TRUE, sizeof(LttEventType), |
401 | events->position); |
402 | //f->events = g_new(LttEventType*,f->event_number); |
403 | f->events = g_array_set_size(f->events, events->position); |
404 | |
405 | g_datalist_init(&f->events_by_name); |
2312de30 |
406 | // g_datalist_init(&f->named_types); |
f104d082 |
407 | #if 0 |
408 | /* The first day, he created the named types */ |
409 | |
410 | for(i=0; i<named_types->keys.position; i++) { |
411 | GQuark name = g_quark_from_string((char*)named_types->keys.array[i]); |
412 | type_descriptor_t *td = (type_descriptor_t*)named_types->values.array[i]; |
413 | |
414 | /* Create the type */ |
415 | type = g_new(LttType,1); |
416 | type->type_name = name; |
417 | type->type_class = td->type; |
418 | if(td->fmt) type->fmt = g_strdup(td->fmt); |
419 | else type->fmt = NULL; |
420 | type->size = td->size; |
421 | type->enum_strings = NULL; |
422 | type->element_type = NULL; |
423 | type->element_number = 0; |
424 | |
425 | construct_types_and_fields(type, td, NULL, NULL, ...); |
426 | |
427 | g_datalist_id_set_data_full(&fac->named_types, name, |
428 | type, (GDestroyNotify)freeLttNamedType); |
429 | |
430 | } |
431 | #endif //0 |
432 | /* The second day, he created the event fields and types */ |
433 | //for each event, construct field and type acyclic graph |
6cd62ccf |
434 | for(i=0;i<events->position;i++){ |
c1161b10 |
435 | event_t *parser_event = (event_t*)events->array[i]; |
f104d082 |
436 | LttEventType *event_type = &g_array_index(f->events, LttEventType, i); |
6cd62ccf |
437 | |
3aee1200 |
438 | event_type->name = |
f104d082 |
439 | g_quark_from_string(parser_event->name); |
3aee1200 |
440 | |
441 | g_datalist_id_set_data(&f->events_by_name, event_type->name, |
442 | event_type); |
443 | |
444 | event_type->description = |
f104d082 |
445 | g_strdup(parser_event->description); |
6cd62ccf |
446 | |
3aee1200 |
447 | event_type->index = i; |
f104d082 |
448 | event_type->facility = f; |
6cd62ccf |
449 | |
dd3a6d39 |
450 | event_type->has_compact_data = parser_event->compact_data; |
451 | |
f104d082 |
452 | event_type->fields = g_array_sized_new(FALSE, TRUE, |
453 | sizeof(LttField), parser_event->fields.position); |
454 | event_type->fields = |
455 | g_array_set_size(event_type->fields, parser_event->fields.position); |
456 | g_datalist_init(&event_type->fields_by_name); |
457 | |
458 | for(j=0; j<parser_event->fields.position; j++) { |
459 | LttField *field = &g_array_index(event_type->fields, LttField, j); |
460 | field_t *parser_field = (field_t*)parser_event->fields.array[j]; |
461 | |
2312de30 |
462 | construct_fields(f, field, parser_field); |
f104d082 |
463 | g_datalist_id_set_data(&event_type->fields_by_name, |
464 | field->name, |
465 | field); |
8710c6c7 |
466 | } |
f104d082 |
467 | } |
468 | |
469 | /* What about 2 days weeks ? */ |
6cd62ccf |
470 | } |
471 | |
472 | |
473 | /***************************************************************************** |
474 | *Function name |
3aee1200 |
475 | * construct_types_and_fields : construct field tree and type graph, |
6cd62ccf |
476 | * internal recursion function |
477 | *Input params |
478 | * fac : facility struct |
f104d082 |
479 | * field : destination lttv field |
480 | * fld : source parser field |
6cd62ccf |
481 | ****************************************************************************/ |
482 | |
f104d082 |
483 | //DONE |
484 | //make the change for arrays and sequences |
485 | //no more root field. -> change this for an array of fields. |
486 | // Compute the field size here. |
487 | // Flag fields as "VARIABLE OFFSET" or "FIXED OFFSET" : as soon as |
488 | // a field with a variable size is found, all the following fields must |
489 | // be flagged with "VARIABLE OFFSET", this will be done by the offset |
490 | // precomputation. |
491 | |
3aee1200 |
492 | |
f104d082 |
493 | void construct_fields(LttFacility *fac, |
c1161b10 |
494 | LttField *field, |
f104d082 |
495 | field_t *fld) |
496 | { |
e8548639 |
497 | char *fmt_type;//gaby |
f104d082 |
498 | guint len; |
499 | type_descriptor_t *td; |
2312de30 |
500 | LttType *type; |
f104d082 |
501 | |
c1161b10 |
502 | if(fld->name) |
503 | field->name = g_quark_from_string(fld->name); |
504 | else |
505 | fld->name = 0; |
ae3d0f50 |
506 | |
f104d082 |
507 | if(fld->description) { |
508 | len = strlen(fld->description); |
509 | field->description = g_new(gchar, len+1); |
510 | strcpy(field->description, fld->description); |
511 | } |
512 | field->dynamic_offsets = NULL; |
513 | type = &field->field_type; |
514 | td = fld->type; |
515 | |
516 | type->enum_map = NULL; |
517 | type->fields = NULL; |
518 | type->fields_by_name = NULL; |
c1161b10 |
519 | type->network = td->network; |
743e50fd |
520 | |
f104d082 |
521 | switch(td->type) { |
522 | case INT_FIXED: |
523 | type->type_class = LTT_INT_FIXED; |
524 | type->size = td->size; |
525 | break; |
526 | case UINT_FIXED: |
527 | type->type_class = LTT_UINT_FIXED; |
528 | type->size = td->size; |
529 | break; |
530 | case POINTER: |
531 | type->type_class = LTT_POINTER; |
532 | type->size = fac->pointer_size; |
533 | break; |
534 | case CHAR: |
535 | type->type_class = LTT_CHAR; |
536 | type->size = td->size; |
537 | break; |
538 | case UCHAR: |
539 | type->type_class = LTT_UCHAR; |
540 | type->size = td->size; |
743e50fd |
541 | g_assert(type->size != 0); |
f104d082 |
542 | break; |
543 | case SHORT: |
544 | type->type_class = LTT_SHORT; |
545 | type->size = td->size; |
546 | break; |
547 | case USHORT: |
548 | type->type_class = LTT_USHORT; |
549 | type->size = td->size; |
550 | break; |
551 | case INT: |
552 | type->type_class = LTT_INT; |
553 | type->size = fac->int_size; |
554 | break; |
555 | case UINT: |
556 | type->type_class = LTT_UINT; |
557 | type->size = fac->int_size; |
743e50fd |
558 | g_assert(type->size != 0); |
f104d082 |
559 | break; |
560 | case LONG: |
561 | type->type_class = LTT_LONG; |
562 | type->size = fac->long_size; |
563 | break; |
564 | case ULONG: |
565 | type->type_class = LTT_ULONG; |
566 | type->size = fac->long_size; |
567 | break; |
568 | case SIZE_T: |
569 | type->type_class = LTT_SIZE_T; |
570 | type->size = fac->size_t_size; |
571 | break; |
572 | case SSIZE_T: |
573 | type->type_class = LTT_SSIZE_T; |
574 | type->size = fac->size_t_size; |
575 | break; |
576 | case OFF_T: |
577 | type->type_class = LTT_OFF_T; |
578 | type->size = fac->size_t_size; |
579 | break; |
580 | case FLOAT: |
581 | type->type_class = LTT_FLOAT; |
582 | type->size = td->size; |
583 | break; |
584 | case STRING: |
585 | type->type_class = LTT_STRING; |
586 | type->size = 0; |
587 | break; |
588 | case ENUM: |
589 | type->type_class = LTT_ENUM; |
590 | type->size = fac->int_size; |
591 | { |
592 | guint i; |
743e50fd |
593 | type->enum_map = g_hash_table_new(g_direct_hash, g_direct_equal); |
880fded3 |
594 | type->lowest_value = G_MAXINT32; |
595 | type->highest_value = G_MININT32; |
f104d082 |
596 | for(i=0; i<td->labels.position; i++) { |
2312de30 |
597 | GQuark value = g_quark_from_string((char*)td->labels.array[i]); |
598 | gint key = *(int*)td->labels_values.array[i]; |
599 | g_hash_table_insert(type->enum_map, (gpointer)key, (gpointer)value); |
880fded3 |
600 | type->highest_value = max(key, type->highest_value); |
601 | type->lowest_value = min(key, type->lowest_value); |
f104d082 |
602 | } |
603 | } |
743e50fd |
604 | g_assert(type->size != 0); |
f104d082 |
605 | break; |
606 | case ARRAY: |
607 | type->type_class = LTT_ARRAY; |
608 | type->size = td->size; |
609 | type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField), |
610 | td->fields.position); |
611 | type->fields = g_array_set_size(type->fields, td->fields.position); |
612 | { |
613 | guint i; |
614 | |
615 | for(i=0; i<td->fields.position; i++) { |
616 | field_t *schild = (field_t*)td->fields.array[i]; |
617 | LttField *dchild = &g_array_index(type->fields, LttField, i); |
618 | |
619 | construct_fields(fac, dchild, schild); |
620 | } |
621 | } |
622 | break; |
623 | case SEQUENCE: |
624 | type->type_class = LTT_SEQUENCE; |
625 | type->size = 0; |
626 | type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField), |
627 | td->fields.position); |
628 | type->fields = g_array_set_size(type->fields, td->fields.position); |
629 | { |
630 | guint i; |
631 | |
632 | for(i=0; i<td->fields.position; i++) { |
633 | field_t *schild = (field_t*)td->fields.array[i]; |
634 | LttField *dchild = &g_array_index(type->fields, LttField, i); |
635 | |
636 | construct_fields(fac, dchild, schild); |
637 | } |
638 | } |
639 | break; |
640 | case STRUCT: |
641 | type->type_class = LTT_STRUCT; |
642 | type->size = 0; // Size not calculated by the parser. |
643 | type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField), |
644 | td->fields.position); |
645 | type->fields = g_array_set_size(type->fields, td->fields.position); |
646 | g_datalist_init(&type->fields_by_name); |
647 | { |
648 | guint i; |
649 | |
650 | for(i=0; i<td->fields.position; i++) { |
651 | field_t *schild = (field_t*)td->fields.array[i]; |
652 | LttField *dchild = &g_array_index(type->fields, LttField, i); |
653 | |
654 | construct_fields(fac, dchild, schild); |
655 | g_datalist_id_set_data(&type->fields_by_name, |
656 | dchild->name, |
657 | dchild); |
658 | } |
659 | } |
660 | break; |
661 | case UNION: |
662 | type->type_class = LTT_UNION; |
663 | type->size = 0; // Size not calculated by the parser. |
664 | type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField), |
665 | td->fields.position); |
666 | type->fields = g_array_set_size(type->fields, td->fields.position); |
667 | g_datalist_init(&type->fields_by_name); |
668 | { |
669 | guint i; |
670 | |
671 | for(i=0; i<td->fields.position; i++) { |
672 | field_t *schild = (field_t*)td->fields.array[i]; |
673 | LttField *dchild = &g_array_index(type->fields, LttField, i); |
674 | |
675 | construct_fields(fac, dchild, schild); |
676 | g_datalist_id_set_data(&type->fields_by_name, |
677 | dchild->name, |
678 | dchild); |
679 | } |
680 | } |
681 | break; |
682 | case NONE: |
683 | default: |
684 | g_error("construct_fields : unknown type"); |
685 | } |
686 | |
687 | field->field_size = type->size; |
688 | |
689 | /* Put the fields as "variable" offset to root first. Then, |
690 | * the offset precomputation will only have to set the FIELD_FIXED until |
691 | * it reaches the first variable length field, then stop. |
692 | */ |
693 | field->fixed_root = FIELD_VARIABLE; |
694 | |
695 | if(td->fmt) { |
696 | len = strlen(td->fmt); |
697 | type->fmt = g_new(gchar, len+1); |
698 | strcpy(type->fmt, td->fmt); |
699 | } |
e8548639 |
700 | //here I should verify syntax based on type. |
701 | //if type is array or sequence or enum, parse_fmt. |
702 | //if type is basic, verify syntax, and allow or not the type format. |
703 | //the code can be integrated in the above code (after testing) |
704 | |
705 | |
706 | |
707 | switch (type->type_class){ |
708 | case LTT_ARRAY: |
709 | case LTT_UNION: |
710 | case LTT_STRUCT: |
711 | case LTT_SEQUENCE: |
712 | if(type->fmt==NULL) |
713 | { |
714 | //Assign a default format for these complex types |
715 | //type->fmt = malloc(11*sizeof(char)); |
716 | type->fmt = g_new(gchar, 11); |
717 | type->fmt = g_strdup("{ %S, %S }");//set a default value for fmt. can directly set header and footer, but kept this way on purpose. |
718 | } |
719 | //Parse the fmt string in order to extract header, separator and footer |
720 | parse_fmt(type->fmt,&(type->header),&(type->separator),&(type->footer)); |
721 | |
722 | break; |
723 | case LTT_SHORT: |
724 | case LTT_INT: |
725 | case LTT_LONG: |
726 | case LTT_SSIZE_T: |
727 | case LTT_INT_FIXED: |
728 | |
729 | if(type->fmt == NULL) |
730 | { |
731 | //Assign a default format string |
732 | //type->fmt = malloc(5*sizeof(char)); |
733 | type->fmt = g_new(gchar, 5); |
734 | type->fmt=g_strdup("%lld"); |
735 | break; |
736 | } |
737 | else |
738 | if(verify_fmt_syntax((type->fmt),&fmt_type)>0) |
739 | switch(fmt_type[0]){ |
740 | case 'd': |
741 | case 'i': |
742 | case 'x': |
743 | case 'X': |
744 | append_ll(&(type->fmt),&fmt_type);//append 'll' to fmt |
745 | break; |
746 | default: |
747 | g_error("Format type '%c' not supported\n",fmt_type[0]); |
748 | break; |
749 | } |
750 | break; |
751 | |
752 | case LTT_USHORT: |
753 | case LTT_UINT: |
754 | case LTT_ULONG: |
755 | case LTT_SIZE_T: |
756 | case LTT_OFF_T: |
757 | case LTT_UINT_FIXED: |
758 | if(type->fmt == NULL) |
759 | { |
760 | //Assign a default format string |
761 | //type->fmt= malloc(5*sizeof(char)); |
762 | type->fmt = g_new(gchar, 5); |
763 | type->fmt=g_strdup("%lld"); |
764 | break; |
765 | } |
766 | else |
767 | if(verify_fmt_syntax((type->fmt),&fmt_type)>0) |
768 | switch(fmt_type[0]){ |
769 | case 'd': |
770 | case 'u': |
771 | case 'o': |
772 | case 'x': |
773 | case 'X': |
774 | append_ll(&(type->fmt),&fmt_type); |
775 | break; |
776 | default: |
777 | g_error("Format type '%c' not supported\n",fmt_type[0]); |
778 | } |
779 | break; |
780 | |
781 | case LTT_CHAR: |
782 | case LTT_UCHAR: |
783 | if(type->fmt == NULL) |
784 | { |
785 | //Assign a default format string |
786 | //type->fmt = malloc(3*sizeof(char)); |
787 | type->fmt = g_new(gchar, 3); |
788 | type->fmt = g_strdup("%c"); |
789 | break; |
790 | } |
791 | else |
792 | if(verify_fmt_syntax((type->fmt),&fmt_type)>1) |
793 | switch(fmt_type[0]){ |
794 | case 'c': |
795 | case 'd': |
796 | case 'u': |
797 | case 'x': |
798 | case 'X': |
799 | case 'o': |
800 | break; |
801 | default: |
802 | g_error("Format type '%c' not supported\n",fmt_type[0]); |
803 | } |
804 | break; |
805 | |
806 | case LTT_FLOAT: |
807 | if(type->fmt == NULL) |
808 | { |
809 | //Assign a default format string |
810 | //type->fmt = malloc(3*sizeof(char)); |
811 | type->fmt = g_new(gchar, 3); |
812 | type->fmt = g_strdup("%g"); |
813 | break; |
814 | } |
815 | else |
816 | if(verify_fmt_syntax((type->fmt),&fmt_type)>0) |
817 | switch(fmt_type[0]){ |
818 | case 'f': |
819 | case 'g': |
820 | case 'G': |
821 | case 'e': |
822 | case 'E': |
823 | break; |
824 | default: |
825 | g_error("Format type '%c' not supported\n",fmt_type[0]); |
826 | } |
827 | break; |
828 | |
829 | case LTT_POINTER: |
830 | if(type->fmt == NULL) |
831 | { |
832 | //Assign a default format string |
833 | //type->fmt = malloc(7*sizeof(char)); |
834 | type->fmt = g_new(gchar, 7); |
835 | type->fmt = g_strdup("0x%llx"); |
836 | break; |
837 | } |
838 | else |
839 | if(verify_fmt_syntax((type->fmt),&fmt_type)>0) |
840 | switch(fmt_type[0]){ |
841 | case 'p': |
842 | //type->fmt = malloc(7*sizeof(char)); |
843 | type->fmt = g_new(gchar, 7); |
844 | type->fmt = g_strdup("0x%llx"); |
845 | break; |
846 | case 'x': |
847 | case 'X': |
848 | case 'd': |
849 | append_ll(&(type->fmt),&fmt_type); |
850 | break; |
851 | default: |
852 | g_error("Format type '%c' not supported\n",fmt_type[0]); |
853 | } |
854 | break; |
855 | |
856 | case LTT_STRING: |
857 | if(type->fmt == NULL) |
858 | { |
859 | //type->fmt = malloc(7*sizeof(char)); |
860 | type->fmt = g_new(gchar, 5); |
861 | type->fmt = g_strdup("\"%s\"");//default value for fmt. |
862 | break; |
863 | } |
864 | else |
865 | if(verify_fmt_syntax((type->fmt),&fmt_type)>0) |
866 | switch(fmt_type[0]){ |
867 | case 's': |
868 | break; |
869 | default: |
870 | g_error("Format type '%c' not supported\n", fmt_type[0]); |
871 | } |
872 | break; |
873 | |
874 | default: |
875 | //missing enum |
876 | break; |
877 | } |
f104d082 |
878 | |
879 | |
e8548639 |
880 | } |
f104d082 |
881 | |
882 | #if 0 |
90699b2b |
883 | void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td, |
3aee1200 |
884 | LttField * fld) |
885 | { |
a0c1f622 |
886 | int i; |
90699b2b |
887 | type_descriptor_t * tmpTd; |
3aee1200 |
888 | |
889 | switch(td->type) { |
cb03932a |
890 | case INT: |
891 | case UINT: |
892 | case FLOAT: |
893 | fld->field_type->size = td->size; |
894 | break; |
895 | case POINTER: |
896 | case LONG: |
897 | case ULONG: |
898 | case SIZE_T: |
899 | case SSIZE_T: |
900 | case OFF_T: |
901 | fld->field_type->size = 0; |
902 | break; |
903 | case STRING: |
904 | fld->field_type->size = 0; |
905 | break; |
906 | case ENUM: |
907 | fld->field_type->element_number = td->labels.position; |
908 | fld->field_type->enum_strings = g_new(GQuark,td->labels.position); |
909 | for(i=0;i<td->labels.position;i++){ |
910 | fld->field_type->enum_strings[i] |
911 | = g_quark_from_string(((char*)(td->labels.array[i]))); |
912 | } |
913 | fld->field_type->size = td->size; |
914 | break; |
915 | |
916 | case ARRAY: |
917 | fld->field_type->element_number = (unsigned)td->size; |
918 | case SEQUENCE: |
3aee1200 |
919 | fld->field_type->element_type = g_new(LttType*,1); |
920 | tmpTd = td->nested_type; |
921 | fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd); |
922 | fld->child = g_new(LttField*, 1); |
923 | fld->child[0] = g_new(LttField, 1); |
924 | |
925 | fld->child[0]->field_type = fld->field_type->element_type[0]; |
926 | fld->child[0]->offset_root = 0; |
927 | fld->child[0]->fixed_root = FIELD_UNKNOWN; |
928 | fld->child[0]->offset_parent = 0; |
929 | fld->child[0]->fixed_parent = FIELD_UNKNOWN; |
930 | fld->child[0]->field_size = 0; |
931 | fld->child[0]->fixed_size = FIELD_UNKNOWN; |
932 | fld->child[0]->parent = fld; |
933 | fld->child[0]->child = NULL; |
934 | fld->child[0]->current_element = 0; |
935 | construct_types_and_fields(fac, tmpTd, fld->child[0]); |
936 | break; |
cb03932a |
937 | |
938 | case STRUCT: |
939 | case UNION: |
3aee1200 |
940 | fld->field_type->element_number = td->fields.position; |
941 | |
942 | g_assert(fld->field_type->element_type == NULL); |
943 | fld->field_type->element_type = g_new(LttType*, td->fields.position); |
944 | |
945 | fld->child = g_new(LttField*, td->fields.position); |
946 | for(i=0;i<td->fields.position;i++){ |
90699b2b |
947 | tmpTd = ((field_t*)(td->fields.array[i]))->type; |
3aee1200 |
948 | |
c1161b10 |
949 | fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd); |
3aee1200 |
950 | fld->child[i] = g_new(LttField,1); |
951 | |
952 | // fld->child[i]->field_pos = i; |
953 | fld->child[i]->field_type = fld->field_type->element_type[i]; |
954 | |
955 | fld->child[i]->field_type->element_name |
c1161b10 |
956 | = g_quark_from_string(((field_t*)(td->fields.array[i]))->name); |
3aee1200 |
957 | |
958 | fld->child[i]->offset_root = 0; |
959 | fld->child[i]->fixed_root = FIELD_UNKNOWN; |
960 | fld->child[i]->offset_parent = 0; |
961 | fld->child[i]->fixed_parent = FIELD_UNKNOWN; |
962 | fld->child[i]->field_size = 0; |
963 | fld->child[i]->fixed_size = FIELD_UNKNOWN; |
964 | fld->child[i]->parent = fld; |
965 | fld->child[i]->child = NULL; |
966 | fld->child[i]->current_element = 0; |
967 | construct_types_and_fields(fac, tmpTd, fld->child[i]); |
968 | } |
3aee1200 |
969 | break; |
cb03932a |
970 | |
3aee1200 |
971 | default: |
972 | g_error("construct_types_and_fields : unknown type"); |
973 | } |
974 | |
975 | |
976 | } |
977 | |
f104d082 |
978 | #endif //0 |
3aee1200 |
979 | |
980 | #if 0 |
981 | void construct_types_and_fields(LttFacility * fac, type_descriptor * td, |
963b5f2d |
982 | LttField * fld) |
6cd62ccf |
983 | { |
908f42fa |
984 | int i, flag; |
6cd62ccf |
985 | type_descriptor * tmpTd; |
986 | |
987 | // if(td->type == LTT_STRING || td->type == LTT_SEQUENCE) |
988 | // fld->field_size = 0; |
989 | // else fld->field_size = -1; |
990 | |
991 | if(td->type == LTT_ENUM){ |
992 | fld->field_type->element_number = td->labels.position; |
3aee1200 |
993 | fld->field_type->enum_strings = g_new(GQuark,td->labels.position); |
6cd62ccf |
994 | for(i=0;i<td->labels.position;i++){ |
995 | fld->field_type->enum_strings[i] |
3aee1200 |
996 | = g_quark_from_string(((char*)(td->labels.array[i]))); |
6cd62ccf |
997 | } |
998 | }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){ |
999 | if(td->type == LTT_ARRAY) |
1000 | fld->field_type->element_number = (unsigned)td->size; |
963b5f2d |
1001 | fld->field_type->element_type = g_new(LttType*,1); |
6cd62ccf |
1002 | tmpTd = td->nested_type; |
1003 | fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd); |
963b5f2d |
1004 | fld->child = g_new(LttField*, 1); |
1005 | fld->child[0] = g_new(LttField, 1); |
6cd62ccf |
1006 | |
3aee1200 |
1007 | // fld->child[0]->field_pos = 0; |
6cd62ccf |
1008 | fld->child[0]->field_type = fld->field_type->element_type[0]; |
1009 | fld->child[0]->offset_root = fld->offset_root; |
1010 | fld->child[0]->fixed_root = fld->fixed_root; |
1011 | fld->child[0]->offset_parent = 0; |
1012 | fld->child[0]->fixed_parent = 1; |
1013 | // fld->child[0]->base_address = NULL; |
1014 | fld->child[0]->field_size = 0; |
1015 | fld->child[0]->field_fixed = -1; |
1016 | fld->child[0]->parent = fld; |
1017 | fld->child[0]->child = NULL; |
1018 | fld->child[0]->current_element = 0; |
3aee1200 |
1019 | construct_types_and_fields(fac, tmpTd, fld->child[0]); |
6cd62ccf |
1020 | }else if(td->type == LTT_STRUCT){ |
1021 | fld->field_type->element_number = td->fields.position; |
908f42fa |
1022 | |
1023 | if(fld->field_type->element_type == NULL){ |
1024 | fld->field_type->element_type = g_new(LttType*, td->fields.position); |
1025 | flag = 1; |
1026 | }else{ |
1027 | flag = 0; |
1028 | } |
1029 | |
963b5f2d |
1030 | fld->child = g_new(LttField*, td->fields.position); |
6cd62ccf |
1031 | for(i=0;i<td->fields.position;i++){ |
8d1e6362 |
1032 | tmpTd = ((type_fields*)(td->fields.array[i]))->type; |
908f42fa |
1033 | |
1034 | if(flag) |
c1161b10 |
1035 | fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd); |
963b5f2d |
1036 | fld->child[i] = g_new(LttField,1); |
6cd62ccf |
1037 | |
1038 | fld->child[i]->field_pos = i; |
1039 | fld->child[i]->field_type = fld->field_type->element_type[i]; |
908f42fa |
1040 | |
1041 | if(flag){ |
c1161b10 |
1042 | fld->child[i]->field_type->element_name |
1043 | = g_quark_from_string(((type_fields*)(td->fields.array[i]))->name); |
908f42fa |
1044 | } |
1045 | |
6cd62ccf |
1046 | fld->child[i]->offset_root = -1; |
1047 | fld->child[i]->fixed_root = -1; |
1048 | fld->child[i]->offset_parent = -1; |
1049 | fld->child[i]->fixed_parent = -1; |
1050 | // fld->child[i]->base_address = NULL; |
1051 | fld->child[i]->field_size = 0; |
1052 | fld->child[i]->field_fixed = -1; |
1053 | fld->child[i]->parent = fld; |
1054 | fld->child[i]->child = NULL; |
1055 | fld->child[i]->current_element = 0; |
3aee1200 |
1056 | construct_types_and_fields(fac, tmpTd, fld->child[i]); |
6cd62ccf |
1057 | } |
1058 | } |
1059 | } |
3aee1200 |
1060 | #endif //0 |
6cd62ccf |
1061 | |
f104d082 |
1062 | #if 0 |
6cd62ccf |
1063 | /***************************************************************************** |
1064 | *Function name |
1065 | * lookup_named_type: search named type in the table |
1066 | * internal function |
1067 | *Input params |
1068 | * fac : facility struct |
f104d082 |
1069 | * name : type name |
6cd62ccf |
1070 | *Return value |
963b5f2d |
1071 | * : either find the named type, or create a new LttType |
6cd62ccf |
1072 | ****************************************************************************/ |
1073 | |
f104d082 |
1074 | LttType * lookup_named_type(LttFacility *fac, GQuark type_name) |
6cd62ccf |
1075 | { |
cb03932a |
1076 | LttType *type = NULL; |
6cd62ccf |
1077 | |
f104d082 |
1078 | /* Named type */ |
1079 | type = g_datalist_id_get_data(&fac->named_types, name); |
1080 | |
1081 | g_assert(type != NULL); |
1082 | #if 0 |
3aee1200 |
1083 | if(type == NULL){ |
cb03932a |
1084 | /* Create the type */ |
3aee1200 |
1085 | type = g_new(LttType,1); |
1086 | type->type_name = name; |
3aee1200 |
1087 | type->type_class = td->type; |
1088 | if(td->fmt) type->fmt = g_strdup(td->fmt); |
1089 | else type->fmt = NULL; |
1090 | type->size = td->size; |
1091 | type->enum_strings = NULL; |
1092 | type->element_type = NULL; |
1093 | type->element_number = 0; |
cb03932a |
1094 | |
1095 | if(td->type_name != NULL) |
1096 | g_datalist_id_set_data_full(&fac->named_types, name, |
1097 | type, (GDestroyNotify)freeLttNamedType); |
6cd62ccf |
1098 | } |
f104d082 |
1099 | #endif //0 |
3aee1200 |
1100 | return type; |
6cd62ccf |
1101 | } |
f104d082 |
1102 | #endif //0 |
6cd62ccf |
1103 | |
1104 | /***************************************************************************** |
1105 | *Function name |
1106 | * ltt_facility_close : close a facility, decrease its usage count, |
1107 | * if usage count = 0, release the memory |
1108 | *Input params |
1109 | * f : facility that will be closed |
6cd62ccf |
1110 | ****************************************************************************/ |
1111 | |
3aee1200 |
1112 | void ltt_facility_close(LttFacility *f) |
6cd62ccf |
1113 | { |
6cd62ccf |
1114 | //release the memory it occupied |
1115 | freeFacility(f); |
6cd62ccf |
1116 | } |
1117 | |
1118 | /***************************************************************************** |
1119 | * Functions to release the memory occupied by the facility |
1120 | ****************************************************************************/ |
1121 | |
963b5f2d |
1122 | void freeFacility(LttFacility * fac) |
6cd62ccf |
1123 | { |
3aee1200 |
1124 | guint i; |
1125 | LttEventType *et; |
6cd62ccf |
1126 | |
3aee1200 |
1127 | for(i=0; i<fac->events->len; i++) { |
1128 | et = &g_array_index (fac->events, LttEventType, i); |
1129 | freeEventtype(et); |
6cd62ccf |
1130 | } |
3aee1200 |
1131 | g_array_free(fac->events, TRUE); |
6cd62ccf |
1132 | |
f104d082 |
1133 | g_datalist_clear(&fac->events_by_name); |
6cd62ccf |
1134 | |
f104d082 |
1135 | // g_datalist_clear(&fac->named_types); |
6cd62ccf |
1136 | } |
1137 | |
963b5f2d |
1138 | void freeEventtype(LttEventType * evType) |
6cd62ccf |
1139 | { |
f104d082 |
1140 | unsigned int i; |
908f42fa |
1141 | LttType * root_type; |
6cd62ccf |
1142 | if(evType->description) |
f104d082 |
1143 | g_free(evType->description); |
1144 | |
1145 | for(i=0; i<evType->fields->len;i++) { |
2312de30 |
1146 | LttField *field = &g_array_index(evType->fields, LttField, i); |
1147 | freeLttField(field); |
1417d990 |
1148 | } |
f104d082 |
1149 | g_array_free(evType->fields, TRUE); |
1150 | g_datalist_clear(&evType->fields_by_name); |
1151 | } |
1152 | |
1153 | void freeLttType(LttType * type) |
1154 | { |
1155 | unsigned int i; |
1156 | |
1157 | if(type->fmt) |
1158 | g_free(type->fmt); |
1159 | |
1160 | if(type->enum_map) |
2312de30 |
1161 | g_hash_table_destroy(type->enum_map); |
f104d082 |
1162 | |
1163 | if(type->fields) { |
1164 | for(i=0; i<type->fields->len; i++) { |
1165 | freeLttField(&g_array_index(type->fields, LttField, i)); |
1166 | } |
1167 | g_array_free(type->fields, TRUE); |
1168 | } |
1169 | if(type->fields_by_name) |
1170 | g_datalist_clear(&type->fields_by_name); |
e8548639 |
1171 | |
1172 | if(type->header) |
1173 | g_free(type->header);//no need for condition? if(type->header) |
1174 | if(type->separator) |
1175 | g_free(type->separator); |
1176 | if(type->footer) |
1177 | g_free(type->footer); |
6cd62ccf |
1178 | } |
1179 | |
908f42fa |
1180 | void freeLttNamedType(LttType * type) |
1181 | { |
f104d082 |
1182 | freeLttType(type); |
908f42fa |
1183 | } |
1184 | |
f104d082 |
1185 | void freeLttField(LttField * field) |
1417d990 |
1186 | { |
f104d082 |
1187 | if(field->description) |
1188 | g_free(field->description); |
1189 | if(field->dynamic_offsets) |
1190 | g_array_free(field->dynamic_offsets, TRUE); |
2312de30 |
1191 | freeLttType(&field->field_type); |
6cd62ccf |
1192 | } |
1193 | |
1194 | /***************************************************************************** |
1195 | *Function name |
1196 | * ltt_facility_name : obtain the facility's name |
1197 | *Input params |
3aee1200 |
1198 | * f : the facility |
6cd62ccf |
1199 | *Return value |
3aee1200 |
1200 | * GQuark : the facility's name |
6cd62ccf |
1201 | ****************************************************************************/ |
1202 | |
3aee1200 |
1203 | GQuark ltt_facility_name(LttFacility *f) |
6cd62ccf |
1204 | { |
1205 | return f->name; |
1206 | } |
1207 | |
1208 | /***************************************************************************** |
1209 | *Function name |
1210 | * ltt_facility_checksum : obtain the facility's checksum |
1211 | *Input params |
3aee1200 |
1212 | * f : the facility |
6cd62ccf |
1213 | *Return value |
3aee1200 |
1214 | * : the checksum of the facility |
6cd62ccf |
1215 | ****************************************************************************/ |
1216 | |
3aee1200 |
1217 | guint32 ltt_facility_checksum(LttFacility *f) |
6cd62ccf |
1218 | { |
1219 | return f->checksum; |
1220 | } |
1221 | |
963b5f2d |
1222 | /***************************************************************************** |
1223 | *Function name |
1224 | * ltt_facility_base_id : obtain the facility base id |
1225 | *Input params |
1226 | * f : the facility |
1227 | *Return value |
1228 | * : the base id of the facility |
1229 | ****************************************************************************/ |
1230 | |
3aee1200 |
1231 | guint ltt_facility_id(LttFacility *f) |
963b5f2d |
1232 | { |
3aee1200 |
1233 | return f->id; |
963b5f2d |
1234 | } |
1235 | |
6cd62ccf |
1236 | /***************************************************************************** |
1237 | *Function name |
1238 | * ltt_facility_eventtype_number: obtain the number of the event types |
1239 | *Input params |
1240 | * f : the facility that will be closed |
1241 | *Return value |
3aee1200 |
1242 | * : the number of the event types |
6cd62ccf |
1243 | ****************************************************************************/ |
1244 | |
3aee1200 |
1245 | guint8 ltt_facility_eventtype_number(LttFacility *f) |
6cd62ccf |
1246 | { |
3aee1200 |
1247 | return (f->events->len); |
6cd62ccf |
1248 | } |
1249 | |
1250 | /***************************************************************************** |
1251 | *Function name |
1252 | * ltt_facility_eventtype_get: obtain the event type according to event id |
1253 | * from 0 to event_number - 1 |
1254 | *Input params |
1255 | * f : the facility that will be closed |
1256 | *Return value |
963b5f2d |
1257 | * LttEventType * : the event type required |
6cd62ccf |
1258 | ****************************************************************************/ |
1259 | |
3aee1200 |
1260 | LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i) |
6cd62ccf |
1261 | { |
c4afd5d8 |
1262 | if(!f->exists) return NULL; |
1263 | |
3aee1200 |
1264 | g_assert(i < f->events->len); |
1265 | return &g_array_index(f->events, LttEventType, i); |
6cd62ccf |
1266 | } |
1267 | |
1268 | /***************************************************************************** |
1269 | *Function name |
1270 | * ltt_facility_eventtype_get_by_name |
1271 | * : obtain the event type according to event name |
1272 | * event name is unique in the facility |
1273 | *Input params |
cf74a6f1 |
1274 | * f : the facility |
6cd62ccf |
1275 | * name : the name of the event |
1276 | *Return value |
963b5f2d |
1277 | * LttEventType * : the event type required |
6cd62ccf |
1278 | ****************************************************************************/ |
1279 | |
3aee1200 |
1280 | LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name) |
6cd62ccf |
1281 | { |
cb03932a |
1282 | LttEventType *et = g_datalist_id_get_data(&f->events_by_name, name); |
a0c1f622 |
1283 | return et; |
6cd62ccf |
1284 | } |
1285 | |