source: git/src/cmdline.c @ 2e70979

RELEASE/1.0RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereostereo-2025walls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since 2e70979 was 2e70979, checked in by Olly Betts <olly@…>, 25 years ago

Updated copyright year ranges

git-svn-id: file:///home/survex-svn/survex/trunk@377 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/* > cmdline.c
2 * Wrapper for GNU getopt which deals with standard options
3 * Copyright (C) 1998-2000 Olly Betts
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24#include <ctype.h>
25#include <errno.h>
26#include <stdio.h>
27#include <string.h>
28
29#include "cmdline.h"
30#include "filename.h"
31
32/* It might be useful to be able to disable all long options on small
33 * platforms like pre-386 DOS and perhaps some PDAs...
34 */
35#if 0
36# define getopt_long(ARGC, ARGV, STR, OPTS, PTR) getopt(ARGC, ARGV, STR)
37#endif
38
39/*
40 * bad command line give:
41 * <problem>
42 *
43 * <short syntax>
44 *
45 * --help gives:
46 * <version>
47 *
48 * <short syntax>
49 *
50 * <table>
51 *
52 * <blurb>
53 *
54 * --version gives:
55 * <version>
56 */
57
58/*
59 * want to cope with optional/required parameters on long options
60 * and also parameters on short options
61 */
62
63static const char newline_tabs[] = "\n\t\t\t\t";
64
65static int argc;
66static char *const *argv;
67static const char *shortopts;
68static const struct option *longopts;
69static int *longind;
70static const struct help_msg *help;
71static int min_args, max_args;
72
73static const char *argv0 = NULL;
74
75void
76cmdline_help(void)
77{
78   while (help->opt) {
79      const char *longopt = 0;
80      int opt = help->opt;
81      const struct option *o = 0;
82
83      if (HLP_ISLONG(opt)) {
84         o = longopts + HLP_DECODELONG(opt);
85         longopt = o->name;
86         opt = o->val;
87      }
88
89      if (isalnum(opt))
90         printf("  -%c,", opt);
91      else
92         fputs("     ", stdout);
93
94      if (longopt) {
95         int len = strlen(longopt);
96         printf(" --%s", longopt);
97         if (o && o->has_arg) {
98            const char *p;
99            len += len + 1;
100
101            if (o->has_arg == optional_argument) {
102               putchar('[');
103               len += 2;
104            }
105
106            putchar('=');
107
108            for (p = longopt; *p ; p++) putchar(toupper(*p));
109
110            if (o->has_arg == optional_argument) putchar(']');
111         }
112         len = (len >> 3) + 2;
113         if (len > 4) len = 0;
114         fputs(newline_tabs + len, stdout);
115      } else {
116         fputs(newline_tabs + 1, stdout);
117      }
118
119      puts(help->msg);
120      help++;
121   }
122   /* FIXME: translate */
123   puts("      --help\t\t\tdisplay this help and exit\n"
124        "      --version\t\t\toutput version information and exit");
125 
126   exit(0);
127}
128
129void
130cmdline_version(void)
131{
132   printf("%s - "PACKAGE" "VERSION"\n", argv0);
133}
134
135void
136cmdline_syntax(void)
137
138   printf("\nSyntax: %s [OPTION]...", argv0);
139   if (min_args) {
140      int i = min_args;
141      while (i--) fputs(" FILE", stdout);
142   } else {
143      if (max_args) fputs(" [FILE]", stdout);
144   }
145   if (max_args == -1) fputs("...", stdout);
146   
147   /* FIXME: not quite right - "..." means an indefinite number */
148   if (max_args > min_args) fputs("...", stdout);
149   putnl();
150}
151
152int
153cmdline_int_arg(void)
154{
155   int result;
156   char *endptr;
157   
158   errno = 0;
159
160   result = strtol(optarg, &endptr, 10);
161
162   if (errno == ERANGE) {
163      fprintf(stderr, "%s: numeric argument `%s' out of range\n", argv0, optarg);
164      cmdline_syntax();
165      exit(0);
166   } else if (*optarg == '\0' || *endptr != '\0') {
167      fprintf(stderr, "%s: argument `%s' not an integer\n", argv0, optarg);
168      cmdline_syntax();
169      exit(0);
170   }
171   
172   return result;
173}
174
175float
176cmdline_float_arg(void)
177{
178   float result;
179   char *endptr;
180   
181   errno = 0;
182
183   result = strtod(optarg, &endptr);
184
185   if (errno == ERANGE) {
186      fprintf(stderr, "%s: numeric argument `%s' out of range\n", argv0, optarg);
187      cmdline_syntax();
188      exit(0);
189   } else if (*optarg == '\0' || *endptr != '\0') {
190      fprintf(stderr, "%s: argument `%s' not a number\n", argv0, optarg);
191      cmdline_syntax();
192      exit(0);
193   }
194   
195   return result;
196}
197
198void
199cmdline_init(int argc_, char *const *argv_, const char *shortopts_,
200             const struct option *longopts_, int *longind_,
201             const struct help_msg *help_,
202             int min_args_, int max_args_)
203{
204   if (!argv0) {
205      argv0 = argv_[0];
206      /* FIXME: tidy up argv0 (remove path and extension) */
207   }
208
209   argc = argc_;
210   argv = argv_;
211   shortopts = shortopts_;
212   longopts = longopts_;
213   longind = longind_;
214   help = help_;
215   min_args = min_args_;
216   max_args = max_args_;
217}
218
219int
220cmdline_getopt(void)
221{
222   int opt = getopt_long(argc, argv, shortopts, longopts, longind);
223
224   if (opt == EOF) {
225      /* check minimum # of args given - if not give syntax message */
226      if (argc - optind < min_args) {
227         /* FIXME: TRANSLATE */
228         fprintf(stderr, "%s: too few arguments\n", argv0);
229         opt = '?';
230      } else if (max_args >= 0 && argc - optind > max_args) {
231         /* FIXME: TRANSLATE */
232         fprintf(stderr, "%s: too many arguments\n", argv0);
233         opt = '?';
234      }
235   }
236
237   switch (opt) {
238    case ':': /* parameter missing */
239    case '?': /* unknown opt, ambiguous match, or extraneous param */
240      /* getopt displays a message for us (unless we set opterr to 0) */
241      /* FIXME: set opterr to 0 so we can translate messages? */
242      cmdline_syntax();
243      /* FIXME: translate */
244      fprintf(stderr, "Try `%s --help' for more information.\n", argv0);
245      exit(0);
246    case HLP_VERSION: /* --version */
247      cmdline_version();
248      exit(0);
249    case HLP_HELP: /* --help */
250      cmdline_version();
251      cmdline_syntax();
252      putchar('\n');
253      cmdline_help();
254      exit(0);
255   }
256   return opt;
257}
Note: See TracBrowser for help on using the repository browser.