]> git.ozlabs.org Git - ccan/blob - ccan/autodata/autodata.h
ttxml: removed cruft from tests
[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_autodata_##name[], *__stop_autodata_##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("autodata_" #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, num;
63  *              char **n = autodata_get(names, &num);
64  *
65  *              for (i = 0; i < num; i++)
66  *                      printf("%s\n", n[i]);
67  *      }
68  */
69 #define autodata_get(name, nump)                                        \
70         ((autodata_##name##_ **)                                        \
71          autodata_get_section(__start_autodata_##name,                  \
72                               __stop_autodata_##name, (nump)))
73 #endif /* HAVE_SECTION_START_STOP */
74
75 /**
76  * autodata_free - free the table returned by autodata_get()
77  * @p: the table.
78  */
79 void autodata_free(void *p);
80
81 /* Internal functions. */
82 #define AUTODATA_VAR__(name, line) autodata_##name##_##line
83 #define AUTODATA_VAR_(name, line) AUTODATA_VAR__(name, line)
84
85 #if HAVE_SECTION_START_STOP
86 void *autodata_get_section(void *start, void *stop, size_t *nump);
87 #else
88 #define AUTODATA_TYPE(name, type)                                       \
89         typedef type autodata_##name##_;                                \
90         static const void *autodata_##name##_ex = &autodata_##name##_ex
91
92 #define AUTODATA_MAGIC ((long)0xFEEDA10DA7AF00D5ULL)
93 #define AUTODATA(name, ptr)                                             \
94         static const autodata_##name##_ *NEEDED                         \
95         AUTODATA_VAR_(name, __LINE__)[4] =                              \
96         { (void *)AUTODATA_MAGIC,                                       \
97           (void *)&AUTODATA_VAR_(name, __LINE__),                       \
98           (ptr),                                                        \
99           (void *)#name }
100
101 #define autodata_get(name, nump)                                        \
102         ((autodata_##name##_ **)                                        \
103          autodata_make_table(&autodata_##name##_ex, #name, (nump)))
104
105 void *autodata_make_table(const void *example, const char *name, size_t *nump);
106 #endif
107
108 #endif /* CCAN_AUTODATA_H */