source: git/src/cmdline.c @ cc6c9fe

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 cc6c9fe was 6dc9a36, checked in by Olly Betts <olly@…>, 24 years ago

"Syntax" now translated

git-svn-id: file:///home/survex-svn/survex/trunk@767 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-2001 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 <float.h>
27#include <stdio.h>
28#include <string.h>
29#include <limits.h>
30
31#include "cmdline.h"
32#include "filename.h"
33
34#include "message.h"
35
36/* It might be useful to be able to disable all long options on small
37 * platforms like pre-386 DOS and perhaps some PDAs...
38 */
39#if 0
40# define getopt_long(ARGC, ARGV, STR, OPTS, PTR) getopt(ARGC, ARGV, STR)
41#endif
42
43/*
44 * bad command line give:
45 * <problem>
46 *
47 * <short syntax>
48 *
49 * --help gives:
50 * <version>
51 *
52 * <short syntax>
53 *
54 * <table>
55 *
56 * <blurb>
57 *
58 * --version gives:
59 * <version>
60 */
61
62/*
63 * want to cope with optional/required parameters on long options
64 * and also parameters on short options
65 */
66
67static const char newline_tabs[] = "\n\t\t\t\t";
68
69static int argc;
70static char * const *argv;
71static const char *shortopts;
72static const struct option *longopts;
73static int *longind;
74static const struct help_msg *help;
75static int min_args, max_args;
76static const char *args_msg = NULL, *extra_msg = NULL;
77
78static const char *argv0 = NULL;
79
80void
81cmdline_help(void)
82{
83   while (help->opt) {
84      const char *longopt = 0;
85      int opt = help->opt;
86      const struct option *o = 0;
87
88      if (HLP_ISLONG(opt)) {
89         o = longopts + HLP_DECODELONG(opt);
90         longopt = o->name;
91         opt = o->val;
92      }
93
94      if (isalnum(opt))
95         printf("  -%c%c", opt, longopt ? ',' : ' ');
96      else
97         fputs("     ", stdout);
98
99      if (longopt) {
100         int len = strlen(longopt);
101         printf(" --%s", longopt);
102         if (o && o->has_arg) {
103            const char *p;
104            len += len + 1;
105
106            if (o->has_arg == optional_argument) {
107               putchar('[');
108               len += 2;
109            }
110
111            putchar('=');
112
113            for (p = longopt; *p ; p++) putchar(toupper(*p));
114
115            if (o->has_arg == optional_argument) putchar(']');
116         }
117         len = (len >> 3) + 2;
118         if (len > 4) len = 0;
119         fputs(newline_tabs + len, stdout);
120      } else {
121         fputs(newline_tabs + 1, stdout);
122      }
123
124      puts(help->msg);
125      help++;
126   }
127   /* TRANSLATE */
128   puts("      --help\t\t\tdisplay this help and exit\n"
129        "      --version\t\t\toutput version information and exit");
130
131   if (extra_msg) {
132      putnl();
133      puts(extra_msg);
134   }
135
136   exit(0);
137}
138
139void
140cmdline_version(void)
141{
142   printf("%s - "PACKAGE" "VERSION"\n", argv0);
143}
144
145void
146cmdline_syntax(void)
147{
148   printf("\n%s: %s", msg(/*Syntax*/49), argv0);
149   if (help->opt) fputs(" [OPTION]...", stdout);
150   if (args_msg) {
151      putchar(' ');
152      puts(args_msg);
153      return;
154   }
155   if (min_args) {
156      int i = min_args;
157      while (i--) fputs(" FILE", stdout);
158   }
159   if (max_args == -1) {
160      if (!min_args) fputs(" [FILE]", stdout);
161      fputs("...", stdout);
162   } else if (max_args > min_args) {
163      int i = max_args - min_args;
164      while (i--) fputs(" [FILE]", stdout);
165   }
166   putnl();
167}
168
169void
170cmdline_set_syntax_message(const char *args, const char *extra)
171{
172   args_msg = args;
173   extra_msg = extra;
174}
175
176int
177cmdline_int_arg(void)
178{
179   long result;
180   char *endptr;
181
182   errno = 0;
183
184   result = strtol(optarg, &endptr, 10);
185
186   if (errno == ERANGE || result > INT_MAX || result < INT_MIN) {
187      fprintf(stderr, "%s: numeric argument `%s' out of range\n",
188              argv0, optarg);
189      cmdline_syntax();
190      exit(1);
191   } else if (*optarg == '\0' || *endptr != '\0') {
192      fprintf(stderr, "%s: argument `%s' not an integer\n",
193              argv0, optarg);
194      cmdline_syntax();
195      exit(1);
196   }
197
198   return (int)result;
199}
200
201double
202cmdline_double_arg(void)
203{
204   double result;
205   char *endptr;
206
207   errno = 0;
208
209   result = strtod(optarg, &endptr);
210
211   if (errno == ERANGE) {
212      fprintf(stderr, "%s: numeric argument `%s' out of range\n",
213              argv0, optarg);
214      cmdline_syntax();
215      exit(1);
216   } else if (*optarg == '\0' || *endptr != '\0') {
217      fprintf(stderr, "%s: argument `%s' not a number\n", argv0, optarg);
218      cmdline_syntax();
219      exit(1);
220   }
221
222   return result;
223}
224
225float
226cmdline_float_arg(void)
227{
228   double result = cmdline_double_arg();
229   if (fabs(result) > FLT_MAX) {
230      fprintf(stderr, "%s: numeric argument `%s' out of range\n",
231              argv0, optarg);
232      cmdline_syntax();
233      exit(1);
234   }
235   return (float)result;
236}
237
238void
239cmdline_init(int argc_, char *const *argv_, const char *shortopts_,
240             const struct option *longopts_, int *longind_,
241             const struct help_msg *help_,
242             int min_args_, int max_args_)
243{
244   if (!argv0) argv0 = argv_[0];
245
246   argc = argc_;
247   argv = argv_;
248   shortopts = shortopts_;
249   longopts = longopts_;
250   longind = longind_;
251   help = help_;
252   min_args = min_args_;
253   max_args = max_args_;
254}
255
256int
257cmdline_getopt(void)
258{
259   int opt = getopt_long(argc, argv, shortopts, longopts, longind);
260
261   if (opt == EOF) {
262      /* check minimum # of args given - if not give syntax message */
263      if (argc - optind < min_args) {
264         /* TRANSLATE */
265         fprintf(stderr, "%s: too few arguments\n", argv0);
266         opt = '?';
267      } else if (max_args >= 0 && argc - optind > max_args) {
268         /* TRANSLATE */
269         fprintf(stderr, "%s: too many arguments\n", argv0);
270         opt = '?';
271      }
272   }
273
274   switch (opt) {
275    case ':': /* parameter missing */
276    case '?': /* unknown opt, ambiguous match, or extraneous param */
277      /* getopt displays a message for us (unless we set opterr to 0) */
278      /* FIXME: set opterr to 0 so we can translate messages? */
279      cmdline_syntax();
280      /* TRANSLATE */
281      fprintf(stderr, "Try `%s --help' for more information.\n", argv0);
282      exit(1);
283    case HLP_VERSION: /* --version */
284      cmdline_version();
285      exit(0);
286    case HLP_HELP: /* --help */
287      cmdline_version();
288      cmdline_syntax();
289      putchar('\n');
290      cmdline_help();
291      exit(0);
292   }
293   return opt;
294}
Note: See TracBrowser for help on using the repository browser.