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)) 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