File: handler.h

package info (click to toggle)
drgn 0.0.33-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,892 kB
  • sloc: python: 59,081; ansic: 51,400; awk: 423; makefile: 339; sh: 113
file content (88 lines) | stat: -rw-r--r-- 2,673 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (c) Meta Platforms, Inc. and affiliates.
// SPDX-License-Identifier: LGPL-2.1-or-later

/**
 * @file
 *
 * Chains of named handlers.
 */

#ifndef DRGN_HANDLER_H
#define DRGN_HANDLER_H

#include <stdbool.h>
#include <stdlib.h>

// This should be embedded as the first member in a structure containing the
// handler implementation.
struct drgn_handler {
	const char *name;
	struct drgn_handler *next;
	bool enabled;
	// Whether this structure and name need to be freed.
	bool free;
};

// This is optimized for frequent drgn_handler_list_for_each_enabled()
// operations; everything else is expected to be rare, so we keep this as small
// as possible.
struct drgn_handler_list {
	// All enabled handlers are first, in order, followed by disabled
	// handlers in no particular order.
	struct drgn_handler *head;
};

// handler->name and handler->free must be initialized.
struct drgn_error *drgn_handler_list_register(struct drgn_handler_list *list,
					      struct drgn_handler *handler,
					      size_t enable_index,
					      const char *what);

struct drgn_error *drgn_handler_list_registered(struct drgn_handler_list *list,
						const char ***names_ret,
						size_t *count_ret);

struct drgn_error *drgn_handler_list_set_enabled(struct drgn_handler_list *list,
						 const char * const *names,
						 size_t count,
						 const char *what);

struct drgn_error *drgn_handler_list_enabled(struct drgn_handler_list *list,
					     const char ***names_ret,
					     size_t *count_ret);

bool drgn_handler_list_disable(struct drgn_handler_list *list,
			       const char *name);

static inline bool drgn_handler_is_last_enabled(struct drgn_handler *handler)
{
	return handler->enabled && (!handler->next || !handler->next->enabled);
}

// Helper to simplify the casting and naming in drgn_handler_list_deinit().
static inline struct drgn_handler *
drgn_handler_free_and_next(struct drgn_handler *handler)
{
	struct drgn_handler *next = handler->next;
	if (handler->free) {
		free((char *)handler->name);
		free(handler);
	}
	return next;
}

// Free all registered handlers, optionally executing a statement for each one.
#define drgn_handler_list_deinit(type, handler, list, ...) do {	\
	type *handler = (type *)(list)->head;			\
	while (handler) {					\
		__VA_ARGS__					\
		handler = (type *)drgn_handler_free_and_next((struct drgn_handler *)handler);\
	}							\
} while (0)

#define drgn_handler_list_for_each_enabled(type, handler, list)		\
	for (type *handler = (type *)(list)->head;			\
	     handler && ((struct drgn_handler *)handler)->enabled;	\
	     handler = (type *)((struct drgn_handler *)handler)->next)

#endif /* DRGN_HANDLER_H */