chiark / gitweb /
tree-wide: drop license boilerplate
[elogind.git] / src / basic / string-table.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #pragma once
4
5 /***
6   This file is part of systemd.
7
8   Copyright 2010 Lennart Poettering
9 ***/
10
11 #include <errno.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/types.h>
16
17 #include "macro.h"
18 #include "parse-util.h"
19 #include "string-util.h"
20
21 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key);
22
23 /* For basic lookup tables with strictly enumerated entries */
24 #define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
25         scope const char *name##_to_string(type i) {                    \
26                 if (i < 0 || i >= (type) ELEMENTSOF(name##_table))      \
27                         return NULL;                                    \
28                 return name##_table[i];                                 \
29         }
30
31 #define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)        \
32         scope type name##_from_string(const char *s) {                  \
33                 return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
34         }
35
36 #define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
37         scope type name##_from_string(const char *s) {                  \
38                 int b;                                                  \
39                 if (!s)                                                 \
40                         return -1;                                      \
41                 b = parse_boolean(s);                                   \
42                 if (b == 0)                                             \
43                         return (type) 0;                                \
44                 else if (b > 0)                                         \
45                         return yes;                                     \
46                 return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
47         }
48
49 #define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \
50         scope int name##_to_string_alloc(type i, char **str) {          \
51                 char *s;                                                \
52                 if (i < 0 || i > max)                                   \
53                         return -ERANGE;                                 \
54                 if (i < (type) ELEMENTSOF(name##_table)) {              \
55                         s = strdup(name##_table[i]);                    \
56                         if (!s)                                         \
57                                 return -ENOMEM;                         \
58                 } else {                                                \
59                         if (asprintf(&s, "%i", i) < 0)                  \
60                                 return -ENOMEM;                         \
61                 }                                                       \
62                 *str = s;                                               \
63                 return 0;                                               \
64         }
65
66 #define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \
67         type name##_from_string(const char *s) {                        \
68                 type i;                                                 \
69                 unsigned u = 0;                                         \
70                 if (!s)                                                 \
71                         return (type) -1;                               \
72                 for (i = 0; i < (type) ELEMENTSOF(name##_table); i++)   \
73                         if (streq_ptr(name##_table[i], s))              \
74                                 return i;                               \
75                 if (safe_atou(s, &u) >= 0 && u <= max)                  \
76                         return (type) u;                                \
77                 return (type) -1;                                       \
78         }                                                               \
79
80
81 #define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope)                    \
82         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
83         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)
84
85 #define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope)   \
86         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
87         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope)
88
89 #define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
90 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
91 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
92 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
93
94 #define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
95
96 /* For string conversions where numbers are also acceptable */
97 #define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max)         \
98         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,)  \
99         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,)
100
101 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \
102         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static)
103 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \
104         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static)