8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#pragma once
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering/***
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering This file is part of systemd.
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering Copyright 2010 Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering systemd is free software; you can redistribute it and/or modify it
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering under the terms of the GNU Lesser General Public License as published by
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering (at your option) any later version.
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering systemd is distributed in the hope that it will be useful, but
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering Lesser General Public License for more details.
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering You should have received a copy of the GNU Lesser General Public License
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering***/
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <errno.h>
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include <stddef.h>
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include <stdio.h>
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include <string.h>
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include <sys/types.h>
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "macro.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "parse-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "string-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poetteringssize_t string_table_lookup(const char * const *table, size_t len, const char *key);
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering/* For basic lookup tables with strictly enumerated entries */
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering scope const char *name##_to_string(type i) { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return NULL; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return name##_table[i]; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering }
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering scope type name##_from_string(const char *s) { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering }
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering scope type name##_from_string(const char *s) { \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering int b; \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering b = parse_boolean(s); \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering if (b == 0) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering return (type) 0; \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering else if (b > 0) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering return yes; \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering }
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering struct __useless_struct_to_allow_trailing_semicolon__
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering struct __useless_struct_to_allow_trailing_semicolon__
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
b18b8662154b46f03ddeac00e52d157c87d474e3Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering/* For string conversions where numbers are also acceptable */
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering int name##_to_string_alloc(type i, char **str) { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering char *s; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (i < 0 || i > max) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return -ERANGE; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (i < (type) ELEMENTSOF(name##_table)) { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering s = strdup(name##_table[i]); \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (!s) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return -ENOMEM; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering } else { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (asprintf(&s, "%i", i) < 0) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return -ENOMEM; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering } \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering *str = s; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return 0; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering } \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering type name##_from_string(const char *s) { \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering type i; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering unsigned u = 0; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (!s) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return (type) -1; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering for (i = 0; i < (type) ELEMENTSOF(name##_table); i++) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (streq_ptr(name##_table[i], s)) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return i; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (safe_atou(s, &u) >= 0 && u <= max) \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return (type) u; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering return (type) -1; \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering } \
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering struct __useless_struct_to_allow_trailing_semicolon__