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