1570af302Sopenharmony_ci#define _BSD_SOURCE 2570af302Sopenharmony_ci#include <unistd.h> 3570af302Sopenharmony_ci#include <wchar.h> 4570af302Sopenharmony_ci#include <string.h> 5570af302Sopenharmony_ci#include <limits.h> 6570af302Sopenharmony_ci#include <stdlib.h> 7570af302Sopenharmony_ci#include "locale_impl.h" 8570af302Sopenharmony_ci#include "stdio_impl.h" 9570af302Sopenharmony_ci 10570af302Sopenharmony_cichar *optarg; 11570af302Sopenharmony_ciint optind=1, opterr=1, optopt, __optpos, __optreset=0; 12570af302Sopenharmony_ci 13570af302Sopenharmony_ci#define optpos __optpos 14570af302Sopenharmony_ciweak_alias(__optreset, optreset); 15570af302Sopenharmony_ci 16570af302Sopenharmony_civoid __getopt_msg(const char *a, const char *b, const char *c, size_t l) 17570af302Sopenharmony_ci{ 18570af302Sopenharmony_ci FILE *f = stderr; 19570af302Sopenharmony_ci b = __lctrans_cur(b); 20570af302Sopenharmony_ci FLOCK(f); 21570af302Sopenharmony_ci fputs(a, f)>=0 22570af302Sopenharmony_ci && fwrite(b, strlen(b), 1, f) 23570af302Sopenharmony_ci && fwrite(c, 1, l, f)==l 24570af302Sopenharmony_ci && putc('\n', f); 25570af302Sopenharmony_ci FUNLOCK(f); 26570af302Sopenharmony_ci} 27570af302Sopenharmony_ci 28570af302Sopenharmony_ciint getopt(int argc, char * const argv[], const char *optstring) 29570af302Sopenharmony_ci{ 30570af302Sopenharmony_ci int i; 31570af302Sopenharmony_ci wchar_t c, d; 32570af302Sopenharmony_ci int k, l; 33570af302Sopenharmony_ci char *optchar; 34570af302Sopenharmony_ci 35570af302Sopenharmony_ci if (!optind || __optreset) { 36570af302Sopenharmony_ci __optreset = 0; 37570af302Sopenharmony_ci __optpos = 0; 38570af302Sopenharmony_ci optind = 1; 39570af302Sopenharmony_ci } 40570af302Sopenharmony_ci 41570af302Sopenharmony_ci if (optind >= argc || !argv[optind]) 42570af302Sopenharmony_ci return -1; 43570af302Sopenharmony_ci 44570af302Sopenharmony_ci if (argv[optind][0] != '-') { 45570af302Sopenharmony_ci if (optstring[0] == '-') { 46570af302Sopenharmony_ci optarg = argv[optind++]; 47570af302Sopenharmony_ci return 1; 48570af302Sopenharmony_ci } 49570af302Sopenharmony_ci return -1; 50570af302Sopenharmony_ci } 51570af302Sopenharmony_ci 52570af302Sopenharmony_ci if (!argv[optind][1]) 53570af302Sopenharmony_ci return -1; 54570af302Sopenharmony_ci 55570af302Sopenharmony_ci if (argv[optind][1] == '-' && !argv[optind][2]) 56570af302Sopenharmony_ci return optind++, -1; 57570af302Sopenharmony_ci 58570af302Sopenharmony_ci if (!optpos) optpos++; 59570af302Sopenharmony_ci if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) { 60570af302Sopenharmony_ci k = 1; 61570af302Sopenharmony_ci c = 0xfffd; /* replacement char */ 62570af302Sopenharmony_ci } 63570af302Sopenharmony_ci optchar = argv[optind]+optpos; 64570af302Sopenharmony_ci optpos += k; 65570af302Sopenharmony_ci 66570af302Sopenharmony_ci if (!argv[optind][optpos]) { 67570af302Sopenharmony_ci optind++; 68570af302Sopenharmony_ci optpos = 0; 69570af302Sopenharmony_ci } 70570af302Sopenharmony_ci 71570af302Sopenharmony_ci if (optstring[0] == '-' || optstring[0] == '+') 72570af302Sopenharmony_ci optstring++; 73570af302Sopenharmony_ci 74570af302Sopenharmony_ci i = 0; 75570af302Sopenharmony_ci d = 0; 76570af302Sopenharmony_ci do { 77570af302Sopenharmony_ci l = mbtowc(&d, optstring+i, MB_LEN_MAX); 78570af302Sopenharmony_ci if (l>0) i+=l; else i++; 79570af302Sopenharmony_ci } while (l && d != c); 80570af302Sopenharmony_ci 81570af302Sopenharmony_ci if (d != c || c == ':') { 82570af302Sopenharmony_ci optopt = c; 83570af302Sopenharmony_ci if (optstring[0] != ':' && opterr) 84570af302Sopenharmony_ci __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); 85570af302Sopenharmony_ci return '?'; 86570af302Sopenharmony_ci } 87570af302Sopenharmony_ci if (optstring[i] == ':') { 88570af302Sopenharmony_ci optarg = 0; 89570af302Sopenharmony_ci if (optstring[i+1] != ':' || optpos) { 90570af302Sopenharmony_ci optarg = argv[optind++]; 91570af302Sopenharmony_ci if (optpos) optarg += optpos; 92570af302Sopenharmony_ci optpos = 0; 93570af302Sopenharmony_ci } 94570af302Sopenharmony_ci if (optind > argc) { 95570af302Sopenharmony_ci optopt = c; 96570af302Sopenharmony_ci if (optstring[0] == ':') return ':'; 97570af302Sopenharmony_ci if (opterr) __getopt_msg(argv[0], 98570af302Sopenharmony_ci ": option requires an argument: ", 99570af302Sopenharmony_ci optchar, k); 100570af302Sopenharmony_ci return '?'; 101570af302Sopenharmony_ci } 102570af302Sopenharmony_ci } 103570af302Sopenharmony_ci return c; 104570af302Sopenharmony_ci} 105570af302Sopenharmony_ci 106570af302Sopenharmony_ciweak_alias(getopt, __posix_getopt); 107