258d4a6c466e64f893ed37cb0ef80afae0e5c23c
[babeltrace.git] / src / ctf-writer / clock-class.c
1 /*
2 * clock-class.c
3 *
4 * Babeltrace CTF writer - Clock class
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "CTF-WRITER-CLOCK-CLASS"
30 #include "logging.h"
31
32 #include "compat/uuid.h"
33 #include <babeltrace2/ctf-writer/utils.h>
34 #include <babeltrace2/ctf-writer/object.h>
35 #include "compat/compiler.h"
36 #include <babeltrace2/types.h>
37 #include "compat/string.h"
38 #include <inttypes.h>
39 #include "common/assert.h"
40
41 #include "assert-pre.h"
42 #include "clock-class.h"
43 #include "object.h"
44
45 static
46 void bt_ctf_clock_class_destroy(struct bt_ctf_object *obj);
47
48 BT_HIDDEN
49 bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
50 {
51 return clock_class && clock_class->name;
52 }
53
54 BT_HIDDEN
55 int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
56 const char *name)
57 {
58 int ret = 0;
59
60 if (!clock_class) {
61 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
62 ret = -1;
63 goto end;
64 }
65
66 if (clock_class->frozen) {
67 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
68 clock_class, bt_ctf_clock_class_get_name(clock_class));
69 ret = -1;
70 goto end;
71 }
72
73 if (!bt_ctf_identifier_is_valid(name)) {
74 BT_LOGW("Clock class's name is not a valid CTF identifier: "
75 "addr=%p, name=\"%s\"",
76 clock_class, name);
77 ret = -1;
78 goto end;
79 }
80
81 if (clock_class->name) {
82 g_string_assign(clock_class->name, name);
83 } else {
84 clock_class->name = g_string_new(name);
85 if (!clock_class->name) {
86 BT_LOGE_STR("Failed to allocate a GString.");
87 ret = -1;
88 goto end;
89 }
90 }
91
92 BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
93 clock_class, name);
94
95 end:
96 return ret;
97 }
98
99 static
100 bool validate_freq(struct bt_ctf_clock_class *clock_class,
101 const char *name, uint64_t freq)
102 {
103 bool is_valid = true;
104
105 if (freq == -1ULL || freq == 0) {
106 BT_LOGW("Invalid parameter: frequency is invalid: "
107 "addr=%p, name=\"%s\", freq=%" PRIu64,
108 clock_class, name, freq);
109 is_valid = false;
110 goto end;
111 }
112
113 end:
114 return is_valid;
115 }
116
117 BT_HIDDEN
118 struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
119 uint64_t freq)
120 {
121 int ret;
122 struct bt_ctf_clock_class *clock_class = NULL;
123
124 BT_LOGD("Creating default clock class object: name=\"%s\"",
125 name);
126
127 if (!validate_freq(NULL, name, freq)) {
128 /* validate_freq() logs errors */
129 goto error;
130 }
131
132 clock_class = g_new0(struct bt_ctf_clock_class, 1);
133 if (!clock_class) {
134 BT_LOGE_STR("Failed to allocate one clock class.");
135 goto error;
136 }
137
138 clock_class->precision = 1;
139 clock_class->frequency = freq;
140 bt_ctf_object_init_shared(&clock_class->base, bt_ctf_clock_class_destroy);
141
142 if (name) {
143 ret = bt_ctf_clock_class_set_name(clock_class, name);
144 if (ret) {
145 /* bt_ctf_clock_class_set_name() logs errors */
146 goto error;
147 }
148 }
149
150 BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
151 clock_class, name);
152 return clock_class;
153 error:
154 BT_CTF_OBJECT_PUT_REF_AND_RESET(clock_class);
155 return clock_class;
156 }
157
158 BT_HIDDEN
159 const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
160 {
161 const char *ret = NULL;
162
163 if (!clock_class) {
164 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
165 goto end;
166 }
167
168 if (clock_class->name) {
169 ret = clock_class->name->str;
170 }
171
172 end:
173 return ret;
174 }
175
176 BT_HIDDEN
177 const char *bt_ctf_clock_class_get_description(
178 struct bt_ctf_clock_class *clock_class)
179 {
180 const char *ret = NULL;
181
182 if (!clock_class) {
183 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
184 goto end;
185 }
186
187 if (clock_class->description) {
188 ret = clock_class->description->str;
189 }
190 end:
191 return ret;
192 }
193
194 BT_HIDDEN
195 int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
196 const char *desc)
197 {
198 int ret = 0;
199
200 if (!clock_class || !desc) {
201 BT_LOGW("Invalid parameter: clock class or description is NULL: "
202 "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
203 clock_class, bt_ctf_clock_class_get_name(clock_class),
204 desc);
205 ret = -1;
206 goto end;
207 }
208
209 if (clock_class->frozen) {
210 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
211 clock_class, bt_ctf_clock_class_get_name(clock_class));
212 ret = -1;
213 goto end;
214 }
215
216 clock_class->description = g_string_new(desc);
217 ret = clock_class->description ? 0 : -1;
218 BT_LOGV("Set clock class's description: addr=%p, "
219 "name=\"%s\", desc=\"%s\"",
220 clock_class, bt_ctf_clock_class_get_name(clock_class), desc);
221 end:
222 return ret;
223 }
224
225 BT_HIDDEN
226 uint64_t bt_ctf_clock_class_get_frequency(
227 struct bt_ctf_clock_class *clock_class)
228 {
229 uint64_t ret = -1ULL;
230
231 if (!clock_class) {
232 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
233 goto end;
234 }
235
236 ret = clock_class->frequency;
237 end:
238 return ret;
239 }
240
241 BT_HIDDEN
242 int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
243 uint64_t freq)
244 {
245 int ret = 0;
246
247 if (!clock_class) {
248 BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
249 "addr=%p, name=\"%s\"",
250 clock_class, bt_ctf_clock_class_get_name(clock_class));
251 ret = -1;
252 goto end;
253 }
254
255 if (!validate_freq(clock_class, bt_ctf_clock_class_get_name(clock_class),
256 freq)) {
257 /* validate_freq() logs errors */
258 goto end;
259 }
260
261 if (clock_class->frozen) {
262 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
263 clock_class, bt_ctf_clock_class_get_name(clock_class));
264 ret = -1;
265 goto end;
266 }
267
268 clock_class->frequency = freq;
269 BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
270 clock_class, bt_ctf_clock_class_get_name(clock_class), freq);
271 end:
272 return ret;
273 }
274
275 BT_HIDDEN
276 uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
277 {
278 uint64_t ret = -1ULL;
279
280 if (!clock_class) {
281 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
282 goto end;
283 }
284
285 ret = clock_class->precision;
286 end:
287 return ret;
288 }
289
290 BT_HIDDEN
291 int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
292 uint64_t precision)
293 {
294 int ret = 0;
295
296 if (!clock_class || precision == -1ULL) {
297 BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
298 "addr=%p, name=\"%s\", precision=%" PRIu64,
299 clock_class, bt_ctf_clock_class_get_name(clock_class),
300 precision);
301 ret = -1;
302 goto end;
303 }
304
305 if (clock_class->frozen) {
306 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
307 clock_class, bt_ctf_clock_class_get_name(clock_class));
308 ret = -1;
309 goto end;
310 }
311
312 clock_class->precision = precision;
313 BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
314 clock_class, bt_ctf_clock_class_get_name(clock_class),
315 precision);
316 end:
317 return ret;
318 }
319
320 BT_HIDDEN
321 int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
322 int64_t *offset_s)
323 {
324 int ret = 0;
325
326 if (!clock_class || !offset_s) {
327 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
328 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
329 clock_class, bt_ctf_clock_class_get_name(clock_class),
330 offset_s);
331 ret = -1;
332 goto end;
333 }
334
335 *offset_s = clock_class->offset_s;
336 end:
337 return ret;
338 }
339
340 BT_HIDDEN
341 int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
342 int64_t offset_s)
343 {
344 int ret = 0;
345
346 if (!clock_class) {
347 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
348 ret = -1;
349 goto end;
350 }
351
352 if (clock_class->frozen) {
353 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
354 clock_class, bt_ctf_clock_class_get_name(clock_class));
355 ret = -1;
356 goto end;
357 }
358
359 clock_class->offset_s = offset_s;
360 BT_LOGV("Set clock class's offset (seconds): "
361 "addr=%p, name=\"%s\", offset-s=%" PRId64,
362 clock_class, bt_ctf_clock_class_get_name(clock_class),
363 offset_s);
364 end:
365 return ret;
366 }
367
368 BT_HIDDEN
369 int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
370 int64_t *offset)
371 {
372 int ret = 0;
373
374 if (!clock_class || !offset) {
375 BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
376 "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
377 clock_class, bt_ctf_clock_class_get_name(clock_class),
378 offset);
379 ret = -1;
380 goto end;
381 }
382
383 *offset = clock_class->offset;
384 end:
385 return ret;
386 }
387
388 BT_HIDDEN
389 int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
390 int64_t offset)
391 {
392 int ret = 0;
393
394 if (!clock_class) {
395 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
396 ret = -1;
397 goto end;
398 }
399
400 if (clock_class->frozen) {
401 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
402 clock_class, bt_ctf_clock_class_get_name(clock_class));
403 ret = -1;
404 goto end;
405 }
406
407 clock_class->offset = offset;
408 BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
409 clock_class, bt_ctf_clock_class_get_name(clock_class), offset);
410 end:
411 return ret;
412 }
413
414 BT_HIDDEN
415 bt_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
416 {
417 int ret = -1;
418
419 if (!clock_class) {
420 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
421 goto end;
422 }
423
424 ret = clock_class->absolute;
425 end:
426 return ret;
427 }
428
429 BT_HIDDEN
430 int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
431 bt_bool is_absolute)
432 {
433 int ret = 0;
434
435 if (!clock_class) {
436 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
437 ret = -1;
438 goto end;
439 }
440
441 if (clock_class->frozen) {
442 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
443 clock_class, bt_ctf_clock_class_get_name(clock_class));
444 ret = -1;
445 goto end;
446 }
447
448 clock_class->absolute = !!is_absolute;
449 BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
450 clock_class, bt_ctf_clock_class_get_name(clock_class),
451 is_absolute);
452 end:
453 return ret;
454 }
455
456 BT_HIDDEN
457 const unsigned char *bt_ctf_clock_class_get_uuid(
458 struct bt_ctf_clock_class *clock_class)
459 {
460 const unsigned char *ret;
461
462 if (!clock_class) {
463 BT_LOGW_STR("Invalid parameter: clock class is NULL.");
464 ret = NULL;
465 goto end;
466 }
467
468 if (!clock_class->uuid_set) {
469 BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
470 clock_class, bt_ctf_clock_class_get_name(clock_class));
471 ret = NULL;
472 goto end;
473 }
474
475 ret = clock_class->uuid;
476 end:
477 return ret;
478 }
479
480 BT_HIDDEN
481 int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
482 const unsigned char *uuid)
483 {
484 int ret = 0;
485
486 if (!clock_class || !uuid) {
487 BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
488 "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
489 clock_class, bt_ctf_clock_class_get_name(clock_class),
490 uuid);
491 ret = -1;
492 goto end;
493 }
494
495 if (clock_class->frozen) {
496 BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
497 clock_class, bt_ctf_clock_class_get_name(clock_class));
498 ret = -1;
499 goto end;
500 }
501
502 memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN);
503 clock_class->uuid_set = 1;
504 BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
505 "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
506 clock_class, bt_ctf_clock_class_get_name(clock_class),
507 (unsigned int) uuid[0],
508 (unsigned int) uuid[1],
509 (unsigned int) uuid[2],
510 (unsigned int) uuid[3],
511 (unsigned int) uuid[4],
512 (unsigned int) uuid[5],
513 (unsigned int) uuid[6],
514 (unsigned int) uuid[7],
515 (unsigned int) uuid[8],
516 (unsigned int) uuid[9],
517 (unsigned int) uuid[10],
518 (unsigned int) uuid[11],
519 (unsigned int) uuid[12],
520 (unsigned int) uuid[13],
521 (unsigned int) uuid[14],
522 (unsigned int) uuid[15]);
523 end:
524 return ret;
525 }
526
527 BT_HIDDEN
528 void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
529 {
530 if (!clock_class || clock_class->frozen) {
531 return;
532 }
533
534 BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
535 clock_class, bt_ctf_clock_class_get_name(clock_class));
536 clock_class->frozen = 1;
537 }
538
539 static
540 void bt_ctf_clock_class_destroy(struct bt_ctf_object *obj)
541 {
542 struct bt_ctf_clock_class *clock_class;
543
544 clock_class = container_of(obj, struct bt_ctf_clock_class, base);
545 BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
546 obj, bt_ctf_clock_class_get_name(clock_class));
547
548 if (clock_class->name) {
549 g_string_free(clock_class->name, TRUE);
550 }
551
552 if (clock_class->description) {
553 g_string_free(clock_class->description, TRUE);
554 }
555
556 g_free(clock_class);
557 }
558
559 BT_HIDDEN
560 int bt_ctf_clock_class_compare(struct bt_ctf_clock_class *clock_class_a,
561 struct bt_ctf_clock_class *clock_class_b)
562 {
563 int ret = 1;
564 BT_ASSERT(clock_class_a);
565 BT_ASSERT(clock_class_b);
566
567 /* Name */
568 if (strcmp(clock_class_a->name->str, clock_class_b->name->str) != 0) {
569 BT_LOGV("Clock classes differ: different names: "
570 "cc-a-name=\"%s\", cc-b-name=\"%s\"",
571 clock_class_a->name->str,
572 clock_class_b->name->str);
573 goto end;
574 }
575
576 /* Description */
577 if (clock_class_a->description) {
578 if (!clock_class_b->description) {
579 BT_LOGV_STR("Clock classes differ: clock class A has a "
580 "description, but clock class B does not.");
581 goto end;
582 }
583
584 if (strcmp(clock_class_a->name->str, clock_class_b->name->str)
585 != 0) {
586 BT_LOGV("Clock classes differ: different descriptions: "
587 "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
588 clock_class_a->description->str,
589 clock_class_b->description->str);
590 goto end;
591 }
592 } else {
593 if (clock_class_b->description) {
594 BT_LOGV_STR("Clock classes differ: clock class A has "
595 "no description, but clock class B has one.");
596 goto end;
597 }
598 }
599
600 /* Frequency */
601 if (clock_class_a->frequency != clock_class_b->frequency) {
602 BT_LOGV("Clock classes differ: different frequencies: "
603 "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
604 clock_class_a->frequency,
605 clock_class_b->frequency);
606 goto end;
607 }
608
609 /* Precision */
610 if (clock_class_a->precision != clock_class_b->precision) {
611 BT_LOGV("Clock classes differ: different precisions: "
612 "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
613 clock_class_a->precision,
614 clock_class_b->precision);
615 goto end;
616 }
617
618 /* Offset (seconds) */
619 if (clock_class_a->offset_s != clock_class_b->offset_s) {
620 BT_LOGV("Clock classes differ: different offsets (seconds): "
621 "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
622 clock_class_a->offset_s,
623 clock_class_b->offset_s);
624 goto end;
625 }
626
627 /* Offset (cycles) */
628 if (clock_class_a->offset != clock_class_b->offset) {
629 BT_LOGV("Clock classes differ: different offsets (cycles): "
630 "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
631 clock_class_a->offset,
632 clock_class_b->offset);
633 goto end;
634 }
635
636 /* UUIDs */
637 if (clock_class_a->uuid_set) {
638 if (!clock_class_b->uuid_set) {
639 BT_LOGV_STR("Clock classes differ: clock class A has a "
640 "UUID, but clock class B does not.");
641 goto end;
642 }
643
644 if (memcmp(clock_class_a->uuid, clock_class_b->uuid,
645 BABELTRACE_UUID_LEN) != 0) {
646 BT_LOGV("Clock classes differ: different UUIDs: "
647 "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
648 "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
649 (unsigned int) clock_class_a->uuid[0],
650 (unsigned int) clock_class_a->uuid[1],
651 (unsigned int) clock_class_a->uuid[2],
652 (unsigned int) clock_class_a->uuid[3],
653 (unsigned int) clock_class_a->uuid[4],
654 (unsigned int) clock_class_a->uuid[5],
655 (unsigned int) clock_class_a->uuid[6],
656 (unsigned int) clock_class_a->uuid[7],
657 (unsigned int) clock_class_a->uuid[8],
658 (unsigned int) clock_class_a->uuid[9],
659 (unsigned int) clock_class_a->uuid[10],
660 (unsigned int) clock_class_a->uuid[11],
661 (unsigned int) clock_class_a->uuid[12],
662 (unsigned int) clock_class_a->uuid[13],
663 (unsigned int) clock_class_a->uuid[14],
664 (unsigned int) clock_class_a->uuid[15],
665 (unsigned int) clock_class_b->uuid[0],
666 (unsigned int) clock_class_b->uuid[1],
667 (unsigned int) clock_class_b->uuid[2],
668 (unsigned int) clock_class_b->uuid[3],
669 (unsigned int) clock_class_b->uuid[4],
670 (unsigned int) clock_class_b->uuid[5],
671 (unsigned int) clock_class_b->uuid[6],
672 (unsigned int) clock_class_b->uuid[7],
673 (unsigned int) clock_class_b->uuid[8],
674 (unsigned int) clock_class_b->uuid[9],
675 (unsigned int) clock_class_b->uuid[10],
676 (unsigned int) clock_class_b->uuid[11],
677 (unsigned int) clock_class_b->uuid[12],
678 (unsigned int) clock_class_b->uuid[13],
679 (unsigned int) clock_class_b->uuid[14],
680 (unsigned int) clock_class_b->uuid[15]);
681 goto end;
682 }
683 } else {
684 if (clock_class_b->uuid_set) {
685 BT_LOGV_STR("Clock classes differ: clock class A has "
686 "no UUID, but clock class B has one.");
687 goto end;
688 }
689 }
690
691 /* Absolute */
692 if (!!clock_class_a->absolute != !!clock_class_b->absolute) {
693 BT_LOGV("Clock classes differ: one is absolute, the other "
694 "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
695 !!clock_class_a->absolute,
696 !!clock_class_b->absolute);
697 goto end;
698 }
699
700 /* Equal */
701 ret = 0;
702
703 end:
704 return ret;
705 }
This page took 0.041932 seconds and 3 git commands to generate.