source: git/src/cmdline.c @ 990fbaf0

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 990fbaf0 was a93df0a, checked in by Olly Betts <olly@…>, 25 years ago

Short syntax messages points user to "--help"

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

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