Safe Communication Framework
0.1.0 build feea4f9
ERTMS/ETCS safe communication (Subset-037 EuroRadio, Subset-098 RBC/RBC), CENELEC EN 50128 SIL 4 oriented
Toggle main menu visibility
Loading...
Searching...
No Matches
config.c
Go to the documentation of this file.
1
8
#include "
safecomm/config/config.h
"
9
10
#include <ctype.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <strings.h>
/* strcasecmp */
15
17
static
char
*
trim
(
char
*s)
18
{
19
size_t
len;
20
size_t
start = 0U;
21
22
if
(s == NULL)
23
{
24
return
s;
25
}
26
while
((s[start] !=
'\0'
) && (isspace((
unsigned
char
)s[start]) != 0))
27
{
28
start++;
29
}
30
if
(start > 0U)
31
{
32
(void)memmove(s, &s[start], strlen(&s[start]) + 1U);
33
}
34
len = strlen(s);
35
while
((len > 0U) && (isspace((
unsigned
char
)s[len - 1U]) != 0))
36
{
37
s[len - 1U] =
'\0'
;
38
len--;
39
}
40
return
s;
41
}
42
44
static
void
strip_inline_comment
(
char
*s)
45
{
46
size_t
i;
47
48
for
(i = 0U; s[i] !=
'\0'
; i++)
49
{
50
if
((s[i] ==
'#'
) && ((i == 0U) || (isspace((
unsigned
char
)s[i - 1U]) != 0)))
51
{
52
s[i] =
'\0'
;
53
return
;
54
}
55
}
56
}
57
58
static
bool
store_entry(
safecomm_config_t
*cfg,
const
char
*key,
const
char
*value)
59
{
60
if
(cfg->count >=
SAFECOMM_CONFIG_MAX_ENTRIES
)
61
{
62
return
false
;
63
}
64
if
((strlen(key) >= SAFECOMM_CONFIG_MAX_KEY_LEN) || (strlen(value) >= SAFECOMM_CONFIG_MAX_VALUE_LEN))
65
{
66
return
false
;
67
}
68
(void)strcpy(cfg->entries[cfg->count].key, key);
69
(void)strcpy(cfg->entries[cfg->count].value, value);
70
cfg->count++;
71
return
true
;
72
}
73
74
safecomm_status_t
safecomm_config_load
(
const
char
*path,
safecomm_config_t
*out)
75
{
76
FILE *fp;
77
char
line[SAFECOMM_CONFIG_MAX_LINE_LEN];
78
79
if
((path == NULL) || (out == NULL))
80
{
81
return
SAFECOMM_STATUS_INVALID_PARAM
;
82
}
83
(void)memset(out, 0,
sizeof
(*out));
84
85
fp = fopen(path,
"re"
);
86
if
(fp == NULL)
87
{
88
return
SAFECOMM_STATUS_TRANSPORT
;
89
}
90
91
while
(fgets(line, (
int
)
sizeof
(line), fp) != NULL)
92
{
93
char
*eq;
94
char
*key;
95
char
*value;
96
size_t
line_len = strlen(line);
97
98
if
((line_len + 1U) ==
sizeof
(line) && (line[line_len - 1U] !=
'\n'
))
99
{
100
(void)fclose(fp);
101
return
SAFECOMM_STATUS_BUFFER_TOO_SMALL
;
/* line longer than the buffer */
102
}
103
104
(void)
trim
(line);
105
if
((line[0] ==
'\0'
) || (line[0] ==
'#'
))
106
{
107
continue
;
108
}
109
110
eq = strchr(line,
'='
);
111
if
(eq == NULL)
112
{
113
continue
;
/* not a key=value line — ignored, not an error */
114
}
115
*eq =
'\0'
;
116
key =
trim
(line);
117
value = eq + 1;
118
strip_inline_comment
(value);
119
value =
trim
(value);
120
121
if
(key[0] ==
'\0'
)
122
{
123
continue
;
124
}
125
if
(!store_entry(out, key, value))
126
{
127
(void)fclose(fp);
128
return
SAFECOMM_STATUS_BUFFER_TOO_SMALL
;
129
}
130
}
131
132
if
(ferror(fp) != 0)
133
{
134
(void)fclose(fp);
135
return
SAFECOMM_STATUS_TRANSPORT
;
136
}
137
(void)fclose(fp);
138
return
SAFECOMM_STATUS_OK
;
139
}
140
141
const
char
*
safecomm_config_get_str
(
const
safecomm_config_t
*cfg,
const
char
*key)
142
{
143
uint32_t i;
144
145
if
((cfg == NULL) || (key == NULL))
146
{
147
return
NULL;
148
}
149
for
(i = 0U; i < cfg->count; i++)
150
{
151
if
(strcmp(cfg->entries[i].key, key) == 0)
152
{
153
return
cfg->entries[i].value;
154
}
155
}
156
return
NULL;
157
}
158
159
safecomm_status_t
safecomm_config_get_u32
(
const
safecomm_config_t
*cfg,
const
char
*key, uint32_t *out)
160
{
161
const
char
*s =
safecomm_config_get_str
(cfg, key);
162
unsigned
long
parsed;
163
char
*end = NULL;
164
165
if
((out == NULL) || (s == NULL) || (s[0] ==
'\0'
))
166
{
167
return
SAFECOMM_STATUS_INVALID_PARAM
;
168
}
169
parsed = strtoul(s, &end, 10);
170
if
((end == s) || (*end !=
'\0'
) || (parsed > 0xFFFFFFFFUL))
171
{
172
return
SAFECOMM_STATUS_INVALID_PARAM
;
173
}
174
*out = (uint32_t)parsed;
175
return
SAFECOMM_STATUS_OK
;
176
}
177
178
safecomm_status_t
safecomm_config_get_bool
(
const
safecomm_config_t
*cfg,
const
char
*key,
bool
*out)
179
{
180
const
char
*s =
safecomm_config_get_str
(cfg, key);
181
182
if
((out == NULL) || (s == NULL))
183
{
184
return
SAFECOMM_STATUS_INVALID_PARAM
;
185
}
186
if
((strcasecmp(s,
"true"
) == 0) || (strcmp(s,
"1"
) == 0))
187
{
188
*out =
true
;
189
return
SAFECOMM_STATUS_OK
;
190
}
191
if
((strcasecmp(s,
"false"
) == 0) || (strcmp(s,
"0"
) == 0))
192
{
193
*out =
false
;
194
return
SAFECOMM_STATUS_OK
;
195
}
196
return
SAFECOMM_STATUS_INVALID_PARAM
;
197
}
trim
static char * trim(char *s)
Definition
config.c:17
strip_inline_comment
static void strip_inline_comment(char *s)
Definition
config.c:44
config.h
File-based configuration for the Safe Communication Framework.
safecomm_config_load
safecomm_status_t safecomm_config_load(const char *path, safecomm_config_t *out)
Load path into out (fully overwrites it).
Definition
config.c:74
SAFECOMM_CONFIG_MAX_ENTRIES
#define SAFECOMM_CONFIG_MAX_ENTRIES
Definition
config.h:52
safecomm_config_get_str
const char * safecomm_config_get_str(const safecomm_config_t *cfg, const char *key)
Raw string value for key.
Definition
config.c:141
safecomm_config_get_bool
safecomm_status_t safecomm_config_get_bool(const safecomm_config_t *cfg, const char *key, bool *out)
Boolean value for key ("true"/"false"/"1"/"0", case-insensitive).
Definition
config.c:178
safecomm_config_get_u32
safecomm_status_t safecomm_config_get_u32(const safecomm_config_t *cfg, const char *key, uint32_t *out)
Unsigned-integer value for key.
Definition
config.c:159
safecomm_status_t
safecomm_status_t
Result of a Safe Communication Framework operation.
Definition
status.h:17
SAFECOMM_STATUS_INVALID_PARAM
@ SAFECOMM_STATUS_INVALID_PARAM
Definition
status.h:19
SAFECOMM_STATUS_BUFFER_TOO_SMALL
@ SAFECOMM_STATUS_BUFFER_TOO_SMALL
Definition
status.h:28
SAFECOMM_STATUS_OK
@ SAFECOMM_STATUS_OK
Definition
status.h:18
SAFECOMM_STATUS_TRANSPORT
@ SAFECOMM_STATUS_TRANSPORT
Definition
status.h:23
safecomm_config_t
A loaded configuration file. Caller-allocated, opaque in use.
Definition
config.h:66
src
config
config.c
Generated by
1.18.0