source: git/src/cmdline.c @ 2109b07

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 2109b07 was acc20b1, checked in by Olly Betts <olly@…>, 25 years ago

Updated to use cmdline

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

  • Property mode set to 100644
File size: 6.4 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 modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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;
72static const char *args_msg = NULL, *extra_msg = NULL;
73
74static const char *argv0 = NULL;
75
76void
77cmdline_help(void)
78{
79   while (help->opt) {
80      const char *longopt = 0;
81      int opt = help->opt;
82      const struct option *o = 0;
83
84      if (HLP_ISLONG(opt)) {
85         o = longopts + HLP_DECODELONG(opt);
86         longopt = o->name;
87         opt = o->val;
88      }
89
90      if (isalnum(opt))
91         printf("  -%c,", opt);
92      else
93         fputs("     ", stdout);
94
95      if (longopt) {
96         int len = strlen(longopt);
97         printf(" --%s", longopt);
98         if (o && o->has_arg) {
99            const char *p;
100            len += len + 1;
101
102            if (o->has_arg == optional_argument) {
103               putchar('[');
104               len += 2;
105            }
106
107            putchar('=');
108
109            for (p = longopt; *p ; p++) putchar(toupper(*p));
110
111            if (o->has_arg == optional_argument) putchar(']');
112         }
113         len = (len >> 3) + 2;
114         if (len > 4) len = 0;
115         fputs(newline_tabs + len, stdout);
116      } else {
117         fputs(newline_tabs + 1, stdout);
118      }
119
120      puts(help->msg);
121      help++;
122   }
123   /* FIXME: translate */
124   puts("      --help\t\t\tdisplay this help and exit\n"
125        "      --version\t\t\toutput version information and exit");
126
127   if (extra_msg) {
128      putnl();
129      puts(extra_msg);
130   }
131   exit(0);
132}
133
134void
135cmdline_version(void)
136{
137   printf("%s - "PACKAGE" "VERSION"\n", argv0);
138}
139
140void
141cmdline_syntax(void)
142
143   printf("\nSyntax: %s", argv0);
144   if (help->opt) fputs(" [OPTION]...", stdout);
145   if (args_msg) {
146      putchar(' ');
147      puts(args_msg);
148      return;
149   }
150   if (min_args) {
151      int i = min_args;
152      while (i--) fputs(" FILE", stdout);
153   } else {
154      if (max_args) fputs(" [FILE]", stdout);
155   }
156   if (max_args == -1) fputs("...", stdout);
157   
158   /* FIXME: not quite right - "..." means an indefinite number */
159   if (max_args > min_args) fputs("...", stdout);
160   putnl();
161}
162
163void
164cmdline_set_syntax_message(const char *args, const char *extra)
165{
166   args_msg = args;
167   extra_msg = extra;
168}
169
170int
171cmdline_int_arg(void)
172{
173   int result;
174   char *endptr;
175   
176   errno = 0;
177
178   result = strtol(optarg, &endptr, 10);
179
180   if (errno == ERANGE) {
181      fprintf(stderr, "%s: numeric argument `%s' out of range\n", argv0, optarg);
182      cmdline_syntax();
183      exit(1);
184   } else if (*optarg == '\0' || *endptr != '\0') {
185      fprintf(stderr, "%s: argument `%s' not an integer\n", argv0, optarg);
186      cmdline_syntax();
187      exit(1);
188   }
189   
190   return result;
191}
192
193double
194cmdline_double_arg(void)
195{
196   double result;
197   char *endptr;
198   
199   errno = 0;
200
201   result = strtod(optarg, &endptr);
202
203   if (errno == ERANGE) {
204      fprintf(stderr, "%s: numeric argument `%s' out of range\n", argv0, optarg);
205      cmdline_syntax();
206      exit(1);
207   } else if (*optarg == '\0' || *endptr != '\0') {
208      fprintf(stderr, "%s: argument `%s' not a number\n", argv0, optarg);
209      cmdline_syntax();
210      exit(1);
211   }
212   
213   return result;
214}
215
216float
217cmdline_float_arg(void)
218{   
219   double result = cmdline_double_arg();
220   if (fabs(result) > FLT_MAX) {
221      fprintf(stderr, "%s: numeric argument `%s' out of range\n", argv0, optarg);
222      cmdline_syntax();
223      exit(1);
224   }
225   return (float)result;
226}
227
228void
229cmdline_init(int argc_, char *const *argv_, const char *shortopts_,
230             const struct option *longopts_, int *longind_,
231             const struct help_msg *help_,
232             int min_args_, int max_args_)
233{
234   if (!argv0) {
235      argv0 = argv_[0];
236      /* FIXME: tidy up argv0 (remove path and extension) */
237   }
238
239   argc = argc_;
240   argv = argv_;
241   shortopts = shortopts_;
242   longopts = longopts_;
243   longind = longind_;
244   help = help_;
245   min_args = min_args_;
246   max_args = max_args_;
247}
248
249int
250cmdline_getopt(void)
251{
252   int opt = getopt_long(argc, argv, shortopts, longopts, longind);
253
254   if (opt == EOF) {
255      /* check minimum # of args given - if not give syntax message */
256      if (argc - optind < min_args) {
257         /* FIXME: TRANSLATE */
258         fprintf(stderr, "%s: too few arguments\n", argv0);
259         opt = '?';
260      } else if (max_args >= 0 && argc - optind > max_args) {
261         /* FIXME: TRANSLATE */
262         fprintf(stderr, "%s: too many arguments\n", argv0);
263         opt = '?';
264      }
265   }
266
267   switch (opt) {
268    case ':': /* parameter missing */
269    case '?': /* unknown opt, ambiguous match, or extraneous param */
270      /* getopt displays a message for us (unless we set opterr to 0) */
271      /* FIXME: set opterr to 0 so we can translate messages? */
272      cmdline_syntax();
273      /* FIXME: translate */
274      fprintf(stderr, "Try `%s --help' for more information.\n", argv0);
275      exit(1);
276    case HLP_VERSION: /* --version */
277      cmdline_version();
278      exit(0);
279    case HLP_HELP: /* --help */
280      cmdline_version();
281      cmdline_syntax();
282      putchar('\n');
283      cmdline_help();
284      exit(0);
285   }
286   return opt;
287}
Note: See TracBrowser for help on using the repository browser.