Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * pg_getopt_ctx.c
4 : : * Thread-safe implementation of getopt()
5 : : *
6 : : * Copyright (c) 1987, 1993, 1994
7 : : * The Regents of the University of California. All rights reserved.
8 : : *
9 : : * Redistribution and use in source and binary forms, with or without
10 : : * modification, are permitted provided that the following conditions
11 : : * are met:
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer.
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in the
16 : : * documentation and/or other materials provided with the distribution.
17 : : * 3. Neither the name of the University nor the names of its contributors
18 : : * may be used to endorse or promote products derived from this software
19 : : * without specific prior written permission.
20 : : *
21 : : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : : *
32 : : * IDENTIFICATION
33 : : * src/port/pg_getopt_ctx.c
34 : : *
35 : : *-------------------------------------------------------------------------
36 : : */
37 : :
38 : : #include "c.h"
39 : :
40 : : #include "port/pg_getopt_ctx.h"
41 : :
42 : : #define BADCH (int)'?'
43 : : #define BADARG (int)':'
44 : : #define EMSG ""
45 : :
46 : : /*
47 : : * Start parsing argc/argv argument vector.
48 : : *
49 : : * This is a re-entrant version of the standard library getopt(3) function.
50 : : * To use, first call pg_getopt_start() to initialize the state, and then call
51 : : * pg_getopt_next() until it returns -1.
52 : : */
53 : : void
36 heikki.linnakangas@i 54 :GNC 5498 : pg_getopt_start(pg_getopt_ctx *ctx, int nargc, char *const *nargv, const char *ostr)
55 : : {
56 : 5498 : ctx->nargc = nargc;
57 : 5498 : ctx->nargv = nargv;
58 : 5498 : ctx->ostr = ostr;
59 : :
60 : 5498 : ctx->optind = 1;
61 : 5498 : ctx->optarg = NULL;
62 : 5498 : ctx->opterr = 1; /* Caller may clear this after the call */
63 : 5498 : ctx->optopt = 0;
64 : :
65 : 5498 : ctx->place = EMSG; /* option letter processing */
66 : 5498 : }
67 : :
68 : : /*
69 : : * Parse next option in argc/argv argument vector
70 : : */
71 : : int
72 : 15220 : pg_getopt_next(pg_getopt_ctx *ctx)
73 : : {
74 : : const char *oli; /* option letter list index */
75 : :
76 [ + - ]: 15220 : if (!*ctx->place)
77 : : { /* update scanning pointer */
78 [ + + + + ]: 15220 : if (ctx->optind >= ctx->nargc || *(ctx->place = ctx->nargv[ctx->optind]) != '-')
79 : : {
80 : 5470 : ctx->place = EMSG;
81 : 5470 : return -1;
82 : : }
83 [ + - + + : 9750 : if (ctx->place[1] && *++ctx->place == '-' && ctx->place[1] == '\0')
- + ]
84 : : { /* found "--" */
36 heikki.linnakangas@i 85 :UNC 0 : ++ctx->optind;
86 : 0 : ctx->place = EMSG;
87 : 0 : return -1;
88 : : }
89 : : } /* option letter okay? */
36 heikki.linnakangas@i 90 [ + - ]:GNC 9750 : if ((ctx->optopt = (int) *ctx->place++) == (int) ':' ||
91 [ - + ]: 9750 : !(oli = strchr(ctx->ostr, ctx->optopt)))
92 : : {
93 : : /*
94 : : * if the user didn't specify '-' as an option, assume it means -1.
95 : : */
36 heikki.linnakangas@i 96 [ # # ]:UNC 0 : if (ctx->optopt == (int) '-')
97 : : {
98 : 0 : ctx->place = EMSG;
99 : 0 : return -1;
100 : : }
101 [ # # ]: 0 : if (!*ctx->place)
102 : 0 : ++ctx->optind;
103 [ # # # # ]: 0 : if (ctx->opterr && *ctx->ostr != ':')
104 : 0 : (void) fprintf(stderr,
105 : : "illegal option -- %c\n", ctx->optopt);
106 : 0 : return BADCH;
107 : : }
36 heikki.linnakangas@i 108 [ + + ]:GNC 9750 : if (*++oli != ':')
109 : : { /* don't need argument */
110 : 590 : ctx->optarg = NULL;
111 [ + - ]: 590 : if (!*ctx->place)
112 : 590 : ++ctx->optind;
113 : : }
114 : : else
115 : : { /* need an argument */
116 [ + + ]: 9160 : if (*ctx->place) /* no white space */
117 : 892 : ctx->optarg = ctx->place;
118 [ - + ]: 8268 : else if (ctx->nargc <= ++ctx->optind)
119 : : { /* no arg */
36 heikki.linnakangas@i 120 :UNC 0 : ctx->place = EMSG;
121 [ # # ]: 0 : if (*ctx->ostr == ':')
122 : 0 : return BADARG;
123 [ # # ]: 0 : if (ctx->opterr)
124 : 0 : (void) fprintf(stderr,
125 : : "option requires an argument -- %c\n",
126 : : ctx->optopt);
127 : 0 : return BADCH;
128 : : }
129 : : else
130 : : /* white space */
36 heikki.linnakangas@i 131 :GNC 8268 : ctx->optarg = ctx->nargv[ctx->optind];
132 : 9160 : ctx->place = EMSG;
133 : 9160 : ++ctx->optind;
134 : : }
135 : 9750 : return ctx->optopt; /* dump back option letter */
136 : : }
|