summaryrefslogtreecommitdiff
path: root/lib/include/util.h
blob: e99be3b83cd16eef698cc935161a10e20cfb6c11 (plain)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
/* SPDX-License-Identifier: GPL-3.0-or-later */
/*
 * Copyright (C) 2018 - David Oberhollenzer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#ifndef UTIL_H
#define UTIL_H

#include <sys/types.h>
#include <stdbool.h>
#include <stddef.h>

#include "config.h"

#ifdef __GNUC__
	#define NORETURN __attribute__((noreturn))
#endif

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

typedef struct {
	const char *name;
	int value;
} enum_map_t;


/*
	Read from fd until end-of-file or a line feed is encountered.

	Returns NULL with errno set on failure. Returns NULL with errno
	cleared if end-of-file is reached.

	The line must be deallocated with free().

	The following transformations are applied:
	 - Space characters are replaced with regular white space characters.
	 - Sequences of space characters are truncated to a single space.
	 - A '#' sign is interpreted as the start of a comment and removed,
	   together with everything that follows.
	 - Padding spaces are removed from the line.
	 - If a '"' is encounterd, the above rules are disabled, until a
	   after the matching '"' is read. A '"' can be escaped by preceeding
	   it with a backslash.
	 - If a second, coresponding '"' is not found, processing fails with
	   errno set to EILSEQ.
	 - If a '%' character is encountered, the next character is expected
	   to be a single digit index into argv. If it is not a digit or
	   outside the bounds set by argc, processing fails and sets errno
	   to EINVAL. On success, the argv value is inserted and processed
	   as described above.
	 - A '%' character can be escaped by writing '%%' or, if inside
	   a double quite string, by writing \%.
	 - An attempt to use such an indexed argument inside an argument
	   expansion, results in failure with errno set to ELOOP.
*/
char *rdline(int fd, int argc, const char *const *argv);

/*
	Split a line of the shape "key = value" into key and value part.

	The key can contain alphanumeric characters and can be padded with
	spaces or tabs.

	The value can be either a sequence of alphanumeric characters, period
	or underscore OR a string in quotation marks. For strings, the
	quotation marks are removed and escape sequences are processed.

	The value may also be padded with spaces or tabs but the line may not
	contain anything else after the value, except for spaces, tabs or
	the '#' symbol which is interpreted as start of a comment.
*/
int splitkv(char *line, char **key, char **value);

/*
	Search through an array of enum_map_t entries to resolve a string to
	a numeric value. The end of the map is indicated by a sentinel entry
	with the name set to NULL.
*/
const enum_map_t *enum_by_name(const enum_map_t *map, const char *name);

/*
	Search through an array of enum_map_t entries to resolve a numeric
	value to a string name. The end of the map is indicated by a sentinel
	entry with the name set to NULL.
*/
const char *enum_to_name(const enum_map_t *map, int value);

#endif /* UTIL_H */