Home | History | Annotate | Line # | Download | only in libntp
      1 /*	$NetBSD: getopt.c,v 1.5 2020/05/25 20:47:24 christos Exp $	*/
      2 
      3 /*
      4  * getopt - get option letter from argv
      5  *
      6  * This is a version of the public domain getopt() implementation by
      7  * Henry Spencer, changed for 4.3BSD compatibility (in addition to System V).
      8  * It allows rescanning of an option list by setting optind to 0 before
      9  * calling, which is why we use it even if the system has its own (in fact,
     10  * this one has a unique name so as not to conflict with the system's).
     11  * Thanks to Dennis Ferguson for the appropriate modifications.
     12  *
     13  * This file is in the Public Domain.
     14  */
     15 
     16 /*LINTLIBRARY*/
     17 
     18 #include <config.h>
     19 #include <stdio.h>
     20 
     21 #include "ntp_stdlib.h"
     22 
     23 #ifdef	lint
     24 #undef	putc
     25 #define	putc	fputc
     26 #endif	/* lint */
     27 
     28 char	*ntp_optarg;	/* Global argument pointer. */
     29 int	ntp_optind = 0;	/* Global argv index. */
     30 int	ntp_opterr = 1;	/* for compatibility, should error be printed? */
     31 int	ntp_optopt;	/* for compatibility, option character checked */
     32 
     33 static char	*scan = NULL;	/* Private scan pointer. */
     34 static const char	*prog = "amnesia";
     35 
     36 /*
     37  * Print message about a bad option.
     38  */
     39 static int
     40 badopt(
     41 	const char *mess,
     42 	int ch
     43 	)
     44 {
     45 	if (ntp_opterr) {
     46 		fputs(prog, stderr);
     47 		fputs(mess, stderr);
     48 		(void) putc(ch, stderr);
     49 		(void) putc('\n', stderr);
     50 	}
     51 	return ('?');
     52 }
     53 
     54 int
     55 ntp_getopt(
     56 	int argc,
     57 	char *argv[],
     58 	const char *optstring
     59 	)
     60 {
     61 	register char c;
     62 	register const char *place;
     63 
     64 	prog = argv[0];
     65 	ntp_optarg = NULL;
     66 
     67 	if (ntp_optind == 0) {
     68 		scan = NULL;
     69 		ntp_optind++;
     70 	}
     71 
     72 	if (scan == NULL || *scan == '\0') {
     73 		if (ntp_optind >= argc
     74 		    || argv[ntp_optind][0] != '-'
     75 		    || argv[ntp_optind][1] == '\0') {
     76 			return (EOF);
     77 		}
     78 		if (argv[ntp_optind][1] == '-'
     79 		    && argv[ntp_optind][2] == '\0') {
     80 			ntp_optind++;
     81 			return (EOF);
     82 		}
     83 
     84 		scan = argv[ntp_optind++]+1;
     85 	}
     86 
     87 	c = *scan++;
     88 	ntp_optopt = c & 0377;
     89 	for (place = optstring; place != NULL && *place != '\0'; ++place)
     90 	    if (*place == c)
     91 		break;
     92 
     93 	if (place == NULL || *place == '\0' || c == ':' || c == '?') {
     94 		return (badopt(": unknown option -", c));
     95 	}
     96 
     97 	place++;
     98 	if (*place == ':') {
     99 		if (*scan != '\0') {
    100 			ntp_optarg = scan;
    101 			scan = NULL;
    102 		} else if (ntp_optind >= argc) {
    103 			return (badopt(": option requires argument -", c));
    104 		} else {
    105 			ntp_optarg = argv[ntp_optind++];
    106 		}
    107 	}
    108 
    109 	return (c & 0377);
    110 }
    111