Skip to content

Commit c4971c1

Browse files
committed
posix: c_lib_ext: implement getsubopt()
The getsubopt() function is required as part of the POSIX_C_LIB_EXT option group. Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
1 parent 558cd49 commit c4971c1

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

lib/posix/c_lib_ext/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ zephyr_library_sources(
1212
getentropy.c
1313
getopt/getopt.c
1414
getopt/getopt_common.c
15+
getopt/getsubopt.c
1516
)
1617

1718
zephyr_library_sources_ifdef(CONFIG_GETOPT_LONG getopt/getopt_long.c)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) 2025 Tenstorrent AI ULC
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdbool.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
11+
#include <zephyr/logging/log.h>
12+
13+
LOG_MODULE_DECLARE(getopt, CONFIG_GETOPT_LOG_LEVEL);
14+
15+
int getsubopt(char **optionp, char *const *keylist, char **valuep)
16+
{
17+
size_t i, len;
18+
char *begin, *end, *eq, *key, *val;
19+
20+
if (optionp == NULL || keylist == NULL) {
21+
LOG_DBG("optionp or keylist is NULL");
22+
return -1;
23+
}
24+
25+
if (valuep != NULL) {
26+
*valuep = NULL;
27+
}
28+
29+
for (i = 0, begin = *optionp, end = begin, eq = NULL, len = strlen(*optionp); i <= len;
30+
++i, ++end) {
31+
32+
char c = *end;
33+
34+
if ((c == '=') && (eq == NULL)) {
35+
eq = end;
36+
} else if (c == ',') {
37+
*end = '\0';
38+
*optionp = end + 1;
39+
break;
40+
} else if (c == '\0') {
41+
*optionp = end;
42+
break;
43+
}
44+
}
45+
46+
key = begin;
47+
if (eq == NULL) {
48+
len = end - begin;
49+
if (valuep != NULL) {
50+
*valuep = NULL;
51+
}
52+
LOG_DBG("key: %.*s", (int)len, key);
53+
} else {
54+
len = eq - begin;
55+
val = eq + 1;
56+
if (valuep != NULL) {
57+
*valuep = val;
58+
}
59+
LOG_DBG("key: %.*s val: %.*s", (int)len, key, (int)(end - val), val);
60+
}
61+
62+
if (len == 0) {
63+
LOG_DBG("zero-length key");
64+
return -1;
65+
}
66+
67+
for (i = 0; true; ++i) {
68+
if (keylist[i] == NULL) {
69+
LOG_DBG("end of keylist of length %zu reached", i);
70+
break;
71+
}
72+
73+
if (strncmp(key, keylist[i], len) != 0) {
74+
continue;
75+
}
76+
77+
if (keylist[i][len] != '\0') {
78+
LOG_DBG("key %.*s does not match keylist[%zu]: %s", (int)len, key, i,
79+
keylist[i]);
80+
continue;
81+
}
82+
83+
return (int)i;
84+
}
85+
86+
return -1;
87+
}

0 commit comments

Comments
 (0)