github.com/afumu/libc@v0.0.6/musl/src/misc/getopt.c (about)

     1  #define _BSD_SOURCE
     2  #include <unistd.h>
     3  #include <wchar.h>
     4  #include <string.h>
     5  #include <limits.h>
     6  #include <stdlib.h>
     7  #include "locale_impl.h"
     8  #include "stdio_impl.h"
     9  
    10  char *optarg;
    11  int optind=1, opterr=1, optopt, __optpos, __optreset=0;
    12  
    13  #define optpos __optpos
    14  weak_alias(__optreset, optreset);
    15  
    16  void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
    17  {
    18  	FILE *f = stderr;
    19  	b = __lctrans_cur(b);
    20  	FLOCK(f);
    21  	fputs(a, f)>=0
    22  	&& fwrite(b, strlen(b), 1, f)
    23  	&& fwrite(c, 1, l, f)==l
    24  	&& putc('\n', f);
    25  	FUNLOCK(f);
    26  }
    27  
    28  int getopt(int argc, char * const argv[], const char *optstring)
    29  {
    30  	int i;
    31  	wchar_t c, d;
    32  	int k, l;
    33  	char *optchar;
    34  
    35  	if (!optind || __optreset) {
    36  		__optreset = 0;
    37  		__optpos = 0;
    38  		optind = 1;
    39  	}
    40  
    41  	if (optind >= argc || !argv[optind])
    42  		return -1;
    43  
    44  	if (argv[optind][0] != '-') {
    45  		if (optstring[0] == '-') {
    46  			optarg = argv[optind++];
    47  			return 1;
    48  		}
    49  		return -1;
    50  	}
    51  
    52  	if (!argv[optind][1])
    53  		return -1;
    54  
    55  	if (argv[optind][1] == '-' && !argv[optind][2])
    56  		return optind++, -1;
    57  
    58  	if (!optpos) optpos++;
    59  	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
    60  		k = 1;
    61  		c = 0xfffd; /* replacement char */
    62  	}
    63  	optchar = argv[optind]+optpos;
    64  	optpos += k;
    65  
    66  	if (!argv[optind][optpos]) {
    67  		optind++;
    68  		optpos = 0;
    69  	}
    70  
    71  	if (optstring[0] == '-' || optstring[0] == '+')
    72  		optstring++;
    73  
    74  	i = 0;
    75  	d = 0;
    76  	do {
    77  		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
    78  		if (l>0) i+=l; else i++;
    79  	} while (l && d != c);
    80  
    81  	if (d != c || c == ':') {
    82  		optopt = c;
    83  		if (optstring[0] != ':' && opterr)
    84  			__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
    85  		return '?';
    86  	}
    87  	if (optstring[i] == ':') {
    88  		optarg = 0;
    89  		if (optstring[i+1] != ':' || optpos) {
    90  			optarg = argv[optind++] + optpos;
    91  			optpos = 0;
    92  		}
    93  		if (optind > argc) {
    94  			optopt = c;
    95  			if (optstring[0] == ':') return ':';
    96  			if (opterr) __getopt_msg(argv[0],
    97  				": option requires an argument: ",
    98  				optchar, k);
    99  			return '?';
   100  		}
   101  	}
   102  	return c;
   103  }
   104  
   105  weak_alias(getopt, __posix_getopt);