/src/wireshark/wsutil/feature_list.c
Line | Count | Source |
1 | | /* feature_list.c |
2 | | * Routines for gathering and handling lists of present/absent features |
3 | | * |
4 | | * Wireshark - Network traffic analyzer |
5 | | * By Gerald Combs <gerald@wireshark.org> |
6 | | * Copyright 1998 Gerald Combs |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | */ |
10 | | |
11 | | #include <stdbool.h> |
12 | | |
13 | | #include "config.h" |
14 | | |
15 | | #include <wsutil/feature_list.h> |
16 | | |
17 | | #if !GLIB_CHECK_VERSION(2, 68, 0) |
18 | | static GString* |
19 | | g_string_find_and_erase(GString *string, const char* find) |
20 | | { |
21 | | /* Find and erases find a single time. */ |
22 | | const char* pos = strstr(string->str, find); |
23 | | if (pos != NULL) { |
24 | | g_string_erase(string, pos - string->str, strlen(find)); |
25 | | } |
26 | | return string; |
27 | | } |
28 | | #endif |
29 | | |
30 | | void |
31 | | with_feature(feature_list l, const char *fmt, ...) |
32 | 128 | { |
33 | 128 | va_list arg; |
34 | 128 | GString *msg = g_string_new("+"); |
35 | 128 | va_start(arg, fmt); |
36 | 128 | g_string_append_vprintf(msg, fmt, arg); |
37 | 128 | va_end(arg); |
38 | | /* Strip "version" from the string */ |
39 | 128 | #if GLIB_CHECK_VERSION(2, 68, 0) |
40 | 128 | g_string_replace(msg, " version", "", 0); |
41 | 128 | g_string_replace(msg, " based on", "", 0); |
42 | | #else |
43 | | g_string_find_and_erase(msg, " version"); |
44 | | g_string_find_and_erase(msg, " based on"); |
45 | | #endif |
46 | 128 | *l = g_list_prepend(*l, g_string_free(msg, FALSE)); |
47 | 128 | } |
48 | | |
49 | | void |
50 | | without_feature(feature_list l, const char *fmt, ...) |
51 | 208 | { |
52 | 208 | va_list arg; |
53 | 208 | GString *msg = g_string_new("-"); |
54 | 208 | va_start(arg, fmt); |
55 | 208 | g_string_append_vprintf(msg, fmt, arg); |
56 | 208 | va_end(arg); |
57 | 208 | *l = g_list_prepend(*l, g_string_free(msg, FALSE)); |
58 | 208 | } |
59 | | |
60 | | static int |
61 | | feature_sort_alpha(const void *a, const void *b) |
62 | 784 | { |
63 | 784 | return g_ascii_strcasecmp((char *)a + 1, (char *)b + 1); |
64 | 784 | } |
65 | | |
66 | | void |
67 | | sort_features(feature_list l) |
68 | 32 | { |
69 | 32 | *l = g_list_sort(*l, feature_sort_alpha); |
70 | 32 | } |
71 | | |
72 | | void |
73 | | separate_features(feature_list l, feature_list with_list, feature_list without_list) |
74 | 32 | { |
75 | 32 | GList *iter; |
76 | 32 | char *data; |
77 | 368 | for (iter = *l; iter != NULL; iter = iter->next) { |
78 | 336 | data = (char *)iter->data; |
79 | 336 | if (data[0] == '+') |
80 | 128 | *with_list = g_list_prepend(*with_list, g_strdup(data)); |
81 | 208 | else |
82 | 208 | *without_list = g_list_prepend(*without_list, g_strdup(data)); |
83 | 336 | } |
84 | 32 | *with_list = g_list_reverse(*with_list); |
85 | 32 | *without_list = g_list_reverse(*without_list); |
86 | 32 | } |
87 | | |
88 | | void |
89 | | free_features(feature_list l) |
90 | 80 | { |
91 | 80 | g_list_free_full(*l, g_free); |
92 | | *l = NULL; |
93 | 80 | } |