hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

getopt.c (2979B)


      1 /*
      2  * getopt() - command option parsing
      3  *
      4  * Gunnar Ritter, Freiburg i. Br., Germany, March 2002.
      5  */
      6 
      7 /*	Sccsid @(#)getopt.c	1.6 (gritter) 12/16/07	*/
      8 
      9 #include	<sys/types.h>
     10 #include	<alloca.h>
     11 #include	<string.h>
     12 #include	"msgselect.h"
     13 
     14 /*
     15  * One should not think that re-implementing this is necessary, but
     16  *
     17  * - Some libcs print weird messages.
     18  *
     19  * - GNU libc getopt() is totally brain-damaged, as it requires special
     20  *   care _not_ to reorder parameters and can't be told to work correctly
     21  *   with ':' as first optstring character at all.
     22  */
     23 
     24 char	*optarg = 0;
     25 int	optind = 1;
     26 int	opterr = 1;
     27 int	optopt = 0;
     28 extern char	*pfmt_label__;
     29 
     30 static void
     31 error(const char *s, int c)
     32 {
     33 	/*
     34 	 * Avoid including <unistd.h>, in case its getopt() declaration
     35 	 * conflicts.
     36 	 */
     37 	extern ssize_t	write(int, const void *, size_t);
     38 	const char	*msg = 0;
     39 	char	*buf, *bp;
     40 
     41 	if (pfmt_label__)
     42 		s = pfmt_label__;
     43 	switch (c) {
     44 	case '?':
     45 		msg = ": " msgselect("I","i") "llegal option -- ";
     46 		break;
     47 	case ':':
     48 		msg = ": " msgselect("O","o") "ption requires an argument -- ";
     49 		break;
     50 	}
     51 	bp = buf = alloca(strlen(s) + strlen(msg) + 2);
     52 	while (*s)
     53 		*bp++ = *s++;
     54 	while (*msg)
     55 		*bp++ = *msg++;
     56 	*bp++ = optopt;
     57 	*bp++ = '\n';
     58 	write(2, buf, bp - buf);
     59 }
     60 
     61 int
     62 getopt(int argc, char *const argv[], const char *optstring)
     63 {
     64 	int	colon;
     65 	static const char	*lastp;
     66 	const char	*curp;
     67 
     68 	if (optstring[0] == ':') {
     69 		colon = 1;
     70 		optstring++;
     71 	} else
     72 		colon = 0;
     73 	if (lastp) {
     74 		curp = lastp;
     75 		lastp = 0;
     76 	} else {
     77 		if (optind >= argc || argv[optind] == 0 ||
     78 				argv[optind][0] != '-' ||
     79 				argv[optind][1] == '\0')
     80 			return -1;
     81 		if (argv[optind][1] == '-' && argv[optind][2] == '\0') {
     82 			optind++;
     83 			return -1;
     84 		}
     85 		curp = &argv[optind][1];
     86 	}
     87 	optopt = curp[0] & 0377;
     88 	while (optstring[0]) {
     89 		if (optstring[0] == ':') {
     90 			optstring++;
     91 			continue;
     92 		}
     93 		if ((optstring[0] & 0377) == optopt) {
     94 			if (optstring[1] == ':') {
     95 				if (curp[1] != '\0') {
     96 					optarg = (char *)&curp[1];
     97 					optind++;
     98 				} else {
     99 					if ((optind += 2) > argc) {
    100 						if (!colon && opterr)
    101 							error(argv[0], ':');
    102 						return colon ? ':' : '?';
    103 					}
    104 					optarg = argv[optind - 1];
    105 				}
    106 			} else {
    107 				if (curp[1] != '\0')
    108 					lastp = &curp[1];
    109 				else
    110 					optind++;
    111 				optarg = 0;
    112 			}
    113 			return optopt;
    114 		}
    115 		optstring++;
    116 	}
    117 	if (!colon && opterr)
    118 		error(argv[0], '?');
    119 	if (curp[1] != '\0')
    120 		lastp = &curp[1];
    121 	else
    122 		optind++;
    123 	optarg = 0;
    124 	return '?';
    125 }
    126 
    127 #ifdef __APPLE__
    128 /*
    129  * Starting with Mac OS 10.5 Leopard, <unistd.h> turns getopt()
    130  * into getopt$UNIX2003() by default. Consequently, this function
    131  * is called instead of the one defined above. However, optind is
    132  * still taken from this file, so in effect, options are not
    133  * properly handled. Defining an own getopt$UNIX2003() function
    134  * works around this issue.
    135  */
    136 int
    137 getopt$UNIX2003(int argc, char *const argv[], const char *optstring)
    138 {
    139 	return getopt(argc, argv, optstring);
    140 }
    141 #endif	/* __APPLE__ */