1bae3cd70SThomas Weißschuh /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2bae3cd70SThomas Weißschuh /*
3bae3cd70SThomas Weißschuh * getopt function definitions for NOLIBC, adapted from musl libc
4bae3cd70SThomas Weißschuh * Copyright (C) 2005-2020 Rich Felker, et al.
5bae3cd70SThomas Weißschuh * Copyright (C) 2025 Thomas Weißschuh <linux@weissschuh.net>
6bae3cd70SThomas Weißschuh */
7bae3cd70SThomas Weißschuh
8*3785289fSThomas Weißschuh /* make sure to include all global symbols */
9*3785289fSThomas Weißschuh #include "nolibc.h"
10*3785289fSThomas Weißschuh
11bae3cd70SThomas Weißschuh #ifndef _NOLIBC_GETOPT_H
12bae3cd70SThomas Weißschuh #define _NOLIBC_GETOPT_H
13bae3cd70SThomas Weißschuh
14bae3cd70SThomas Weißschuh struct FILE;
15bae3cd70SThomas Weißschuh static struct FILE *const stderr;
16bae3cd70SThomas Weißschuh static int fprintf(struct FILE *stream, const char *fmt, ...);
17bae3cd70SThomas Weißschuh
18bae3cd70SThomas Weißschuh __attribute__((weak,unused,section(".data.nolibc_getopt")))
19bae3cd70SThomas Weißschuh char *optarg;
20bae3cd70SThomas Weißschuh
21bae3cd70SThomas Weißschuh __attribute__((weak,unused,section(".data.nolibc_getopt")))
22bae3cd70SThomas Weißschuh int optind = 1, opterr = 1, optopt;
23bae3cd70SThomas Weißschuh
24bae3cd70SThomas Weißschuh static __attribute__((unused))
getopt(int argc,char * const argv[],const char * optstring)25bae3cd70SThomas Weißschuh int getopt(int argc, char * const argv[], const char *optstring)
26bae3cd70SThomas Weißschuh {
27bae3cd70SThomas Weißschuh static int __optpos;
28bae3cd70SThomas Weißschuh int i;
29bae3cd70SThomas Weißschuh char c, d;
30bae3cd70SThomas Weißschuh char *optchar;
31bae3cd70SThomas Weißschuh
32bae3cd70SThomas Weißschuh if (!optind) {
33bae3cd70SThomas Weißschuh __optpos = 0;
34bae3cd70SThomas Weißschuh optind = 1;
35bae3cd70SThomas Weißschuh }
36bae3cd70SThomas Weißschuh
37bae3cd70SThomas Weißschuh if (optind >= argc || !argv[optind])
38bae3cd70SThomas Weißschuh return -1;
39bae3cd70SThomas Weißschuh
40bae3cd70SThomas Weißschuh if (argv[optind][0] != '-') {
41bae3cd70SThomas Weißschuh if (optstring[0] == '-') {
42bae3cd70SThomas Weißschuh optarg = argv[optind++];
43bae3cd70SThomas Weißschuh return 1;
44bae3cd70SThomas Weißschuh }
45bae3cd70SThomas Weißschuh return -1;
46bae3cd70SThomas Weißschuh }
47bae3cd70SThomas Weißschuh
48bae3cd70SThomas Weißschuh if (!argv[optind][1])
49bae3cd70SThomas Weißschuh return -1;
50bae3cd70SThomas Weißschuh
51bae3cd70SThomas Weißschuh if (argv[optind][1] == '-' && !argv[optind][2])
52bae3cd70SThomas Weißschuh return optind++, -1;
53bae3cd70SThomas Weißschuh
54bae3cd70SThomas Weißschuh if (!__optpos)
55bae3cd70SThomas Weißschuh __optpos++;
56bae3cd70SThomas Weißschuh c = argv[optind][__optpos];
57bae3cd70SThomas Weißschuh optchar = argv[optind] + __optpos;
58bae3cd70SThomas Weißschuh __optpos++;
59bae3cd70SThomas Weißschuh
60bae3cd70SThomas Weißschuh if (!argv[optind][__optpos]) {
61bae3cd70SThomas Weißschuh optind++;
62bae3cd70SThomas Weißschuh __optpos = 0;
63bae3cd70SThomas Weißschuh }
64bae3cd70SThomas Weißschuh
65bae3cd70SThomas Weißschuh if (optstring[0] == '-' || optstring[0] == '+')
66bae3cd70SThomas Weißschuh optstring++;
67bae3cd70SThomas Weißschuh
68bae3cd70SThomas Weißschuh i = 0;
69bae3cd70SThomas Weißschuh d = 0;
70bae3cd70SThomas Weißschuh do {
71bae3cd70SThomas Weißschuh d = optstring[i++];
72bae3cd70SThomas Weißschuh } while (d && d != c);
73bae3cd70SThomas Weißschuh
74bae3cd70SThomas Weißschuh if (d != c || c == ':') {
75bae3cd70SThomas Weißschuh optopt = c;
76bae3cd70SThomas Weißschuh if (optstring[0] != ':' && opterr)
77bae3cd70SThomas Weißschuh fprintf(stderr, "%s: unrecognized option: %c\n", argv[0], *optchar);
78bae3cd70SThomas Weißschuh return '?';
79bae3cd70SThomas Weißschuh }
80bae3cd70SThomas Weißschuh if (optstring[i] == ':') {
81bae3cd70SThomas Weißschuh optarg = 0;
82bae3cd70SThomas Weißschuh if (optstring[i + 1] != ':' || __optpos) {
83bae3cd70SThomas Weißschuh optarg = argv[optind++];
84bae3cd70SThomas Weißschuh if (__optpos)
85bae3cd70SThomas Weißschuh optarg += __optpos;
86bae3cd70SThomas Weißschuh __optpos = 0;
87bae3cd70SThomas Weißschuh }
88bae3cd70SThomas Weißschuh if (optind > argc) {
89bae3cd70SThomas Weißschuh optopt = c;
90bae3cd70SThomas Weißschuh if (optstring[0] == ':')
91bae3cd70SThomas Weißschuh return ':';
92bae3cd70SThomas Weißschuh if (opterr)
93bae3cd70SThomas Weißschuh fprintf(stderr, "%s: option requires argument: %c\n",
94bae3cd70SThomas Weißschuh argv[0], *optchar);
95bae3cd70SThomas Weißschuh return '?';
96bae3cd70SThomas Weißschuh }
97bae3cd70SThomas Weißschuh }
98bae3cd70SThomas Weißschuh return c;
99bae3cd70SThomas Weißschuh }
100bae3cd70SThomas Weißschuh
101bae3cd70SThomas Weißschuh #endif /* _NOLIBC_GETOPT_H */
102