root/trunk/OpenMeshD/OpenMesh/Tools/Utils/getopt.d

Revision 135, 7.8 kB (checked in by baxissimo, 6 years ago)

Massive cleanup and unification of header comments.

Line 
1 //============================================================================
2 // getopt.d -
3 // Written in the D Programming Language (http://www.digitalmars.com/d)
4 /*****************************************************************************
5  * Description:
6  *   <TODO:>
7  *
8  * Author:  William V. Baxter III, OLM Digital, Inc.
9  * Created: 28 Aug 2007
10  * Copyright:
11  *     Copyright (c) 2007-2008 Bill Baxter, OLM Digital, Inc. (D version)
12  *     Copyright (c) 1987, 1993, 1994
13  *     The Regents of the University of California.  All rights reserved.
14  * License:
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. All advertising materials mentioning features or use of this software
25  *    must display the following acknowledgement:
26  *  This product includes software developed by the University of
27  *  California, Berkeley and its contributors.
28  * 4. Neither the name of the University nor the names of its contributors
29  *    may be used to endorse or promote products derived from this software
30  *    without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  */
44 //============================================================================
45
46 module OpenMesh.Tools.Utils.getopt;
47
48 //import OpenMesh.Core.System.compiler;
49
50 import std.stdio;
51 import std.string;
52 import std.c.string;
53
54 // PUBLIC VARIABLES
55 int opterr = 1,     /* if error message should be printed */
56     optind = 1,     /* index into parent argv vector */
57     optopt,         /* character checked for validity */
58     optreset;       /* reset getopt */
59 string  optarg;     /* argument associated with option */
60
61 const BADCH  = cast(int)'?';
62 const BADARG = cast(int)':';
63
64 /*
65  * getopt --
66  *  Parse argc/argv argument vector.
67  *
68  * The getopt function gets the next option argument from the
69  * argument list specified by the argv and argc arguments. Normally
70  * these values come directly from the arguments received by main.
71  *
72  * The options argument is a string that specifies the option
73  * characters that are valid for this program. An option character in
74  * this string can be followed by a colon (`:') to indicate that it
75  * takes a required argument.
76  *
77  * getopt has three ways to deal with options that follow non-options
78  * argv elements. The special argument `--' forces in all cases the
79  * end of option scanning.
80  *
81  *       * The default is to permute the contents of argv while scanning it
82  *         so that eventually all the non-options are at the end. This
83  *         allows options to be given in any order, even with programs
84  *         that were not written to expect this.
85  *
86  *       * If the options argument string begins with a hyphen (`-'), this
87  *         is treated specially. It permits arguments that are not
88  *          options to be returned as if they were associated with
89  *          option character `\1'.
90  *
91  *    The getopt function returns the option character for the
92  *    next command line option. When no more option arguments
93  *    are available, it returns -1. There may still be more
94  *    non-option arguments; you must compare the external
95  *    variable optind against the argc parameter to check this.
96  *
97  * If the option has an argument, getopt returns the argument by
98  * storing it in the variable optarg. You don't ordinarily need to
99  * copy the optarg string, since it is a pointer into the original
100  * argv array, not into a static area that might be overwritten.
101  *
102  *    If getopt finds an option character in argv that was not
103  *    included in options, or a missing option argument, it returns
104  *    `?' and sets the external variable optopt to the actual
105  *    option character. If the first character of options is a
106  *    colon (`:'), then getopt returns `:' instead of `?' to
107  *    indicate a missing option argument. In addition, if the
108  *    external variable opterr is nonzero (which is the default),
109  *    getopt prints an error message.
110  */
111 int getopt(string[] nargv, string ostr)
112 {
113     int nargc = nargv.length;
114    
115     string __progname = nargv[0];
116
117     static char* place = "";      /* option letter processing */
118     char *oli;              /* option letter list index */
119
120     if (optreset || !*place) {      /* update scanning pointer */
121         optreset = 0;
122         if (optind >= nargc || *(place = nargv[optind].ptr) != '-') {
123             place = "";
124             return (-1);
125         }
126         if (place[1] && *++place == '-') {  /* found "--" */
127             ++optind;
128             place = "";
129             return (-1);
130         }
131     }                   /* option letter okay? */
132     if ((optopt = cast(int)*place++) == cast(int)':' ||
133         (null==(oli = strchr(toStringz(ostr), optopt))))
134     {
135         /*
136          * if the user didn't specify '-' as an option,
137          * assume it means -1.
138          */
139         if (optopt == cast(int)'-')
140             return (-1);
141         if (!*place)
142             ++optind;
143         if (opterr && *ostr != ':') {
144             fwritefln(stderr,
145                       "%s: illegal option -- %s\n", __progname, cast(char)optopt);
146         }
147         return (BADCH);
148     }
149     if (*++oli != ':') {            /* don't need argument */
150         optarg = null;
151         if (!*place)
152             ++optind;
153     }
154     else {                  /* need an argument */
155         if (*place)         /* no white space */
156             optarg = place[0..strlen(place)];
157         else if (nargc <= ++optind) {   /* no arg */
158             place = "";
159             if (*ostr == ':')
160                 return (BADARG);
161             if (opterr) {
162                 fwritefln(stderr,
163                           "%s: option requires an argument -- %c\n",
164                           __progname, optopt);
165             }
166             return (BADCH);
167         }
168         else                /* white space */
169             optarg = nargv[optind];
170         place = "";
171         ++optind;
172     }
173     return (optopt);            /* dump back option letter */
174 }
175
176
177 unittest {
178     int c;
179     uint ALL = 0xf;
180     uint got = 0;
181     while ( (c=getopt(["program", "-h", "-t", "-f", "filename", "-b"], "bhf:t")) != -1 )
182     {
183         switch (c) {
184         case 'h':
185             got |= 1u;
186             break;
187         case 't':
188             got |= 2u;
189             break;
190         case 'f':
191             got |= 4u;
192             assert(optarg == "filename");
193             break;
194         case 'b':
195             got |= 8u;
196             break;
197         default:
198             std.stdio.writefln("ERROR: %s", cast(char)c);
199         }
200     }
201     assert(got == ALL, std.string.format("Got was just ", got, ", not ", ALL));
202 }
203
204 //--- Emacs setup ---
205 // Local Variables:
206 // c-basic-offset: 4
207 // indent-tabs-mode: nil
208 // End:
Note: See TracBrowser for help on using the browser.