]> git.ozlabs.org Git - ccan/blob - ccan/autodata/autodata.h
agar: Add static graph initializer
[ccan] / ccan / autodata / autodata.h
1 // Licensed under BSD-MIT: See LICENSE.
2 #ifndef CCAN_AUTODATA_H
3 #define CCAN_AUTODATA_H
4 #include "config.h"
5 #include <ccan/compiler/compiler.h>
6 #include <stdlib.h>
7
8 #if HAVE_SECTION_START_STOP
9
10 /**
11  * AUTODATA_TYPE - declare the type for a given autodata name.
12  * @name: the name for this set of autodata
13  * @type: the type this autodata points to
14  *
15  * This macro is usually placed in a header: it must preceed any
16  * autodata functions in the file.
17  *
18  * Example:
19  *      #include <ccan/autodata/autodata.h>
20  *
21  *      // My set of char pointers.
22  *      AUTODATA_TYPE(names, char);
23  */
24 #define AUTODATA_TYPE(name, type)                                       \
25         typedef type autodata_##name##_;                                \
26         extern type *__start_xautodata_##name[], *__stop_xautodata_##name[]
27
28 /**
29  * AUTODATA - add a pointer to this autodata set
30  * @name: the name of the set of autodata
31  * @ptr: the compile-time-known pointer
32  *
33  * This embeds @ptr into the binary, with the tag corresponding to
34  * @name (which must look like a valid identifier, no punctuation!).
35  * The type of @ptr must match that given by AUTODATA_TYPE.  It is
36  * usually a file-level declaration.
37  *
38  * Example:
39  *      // Put two char pointers into the names AUTODATA set.
40  *      AUTODATA(names, "Arabella");
41  *      AUTODATA(names, "Alex");
42  */
43 #define AUTODATA(name, ptr) \
44         static const autodata_##name##_ *NEEDED         \
45         __attribute__((section("xautodata_" #name)))    \
46         AUTODATA_VAR_(name, __LINE__) = (ptr);
47
48 /**
49  * autodata_get - get an autodata set
50  * @name: the name of the set of autodata
51  * @nump: the number of items in the set.
52  *
53  * This extract the embedded pointers matching @name.  It may fail
54  * if malloc() fails, or if there is no AUTODATA at all.
55  *
56  * The return will be a pointer to an array of @type pointers (from
57  * AUTODATA_TYPE).
58  *
59  * Example:
60  *      static void print_embedded_names(void)
61  *      {
62  *              unsigned int i;
63  *              size_t num;
64  *              char **n = autodata_get(names, &num);
65  *
66  *              for (i = 0; i < num; i++)
67  *                      printf("%s\n", n[i]);
68  *      }
69  */
70 #define autodata_get(name, nump)                                        \
71         ((autodata_##name##_ **)                                        \
72          autodata_get_section(__start_xautodata_##name,                 \
73                               __stop_xautodata_##name, (nump)))
74 #endif /* HAVE_SECTION_START_STOP */
75
76 /**
77  * autodata_free - free the table returned by autodata_get()
78  * @p: the table.
79  */
80 void autodata_free(void *p);
81
82 /* Internal functions. */
83 #define AUTODATA_VAR__(name, line) autodata_##name##_##line
84 #define AUTODATA_VAR_(name, line) AUTODATA_VAR__(name, line)
85
86 #if HAVE_SECTION_START_STOP
87 void *autodata_get_section(void *start, void *stop, size_t *nump);
88 #else
89 #define AUTODATA_TYPE(name, type)                                       \
90         typedef type autodata_##name##_;                                \
91         static const void *autodata_##name##_ex = &autodata_##name##_ex
92
93 #define AUTODATA_MAGIC ((long)0xFEEDA10DA7AF00D5ULL)
94 #define AUTODATA(name, ptr)                                             \
95         static const autodata_##name##_ *NEEDED                         \
96         AUTODATA_VAR_(name, __LINE__)[4] =                              \
97         { (void *)AUTODATA_MAGIC,                                       \
98           (void *)&AUTODATA_VAR_(name, __LINE__),                       \
99           (ptr),                                                        \
100           (void *)#name }
101
102 #define autodata_get(name, nump)                                        \
103         ((autodata_##name##_ **)                                        \
104          autodata_make_table(&autodata_##name##_ex, #name, (nump)))
105
106 void *autodata_make_table(const void *example, const char *name, size_t *nump);
107 #endif
108
109 #endif /* CCAN_AUTODATA_H */