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
RevLine 
[aadc86e]1/* > cmdline.c
2 * Wrapper for GNU getopt which deals with standard options
[2e70979]3 * Copyright (C) 1998-2000 Olly Betts
[846746e]4 *
[89231c4]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.
[846746e]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
[89231c4]12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
[846746e]14 *
[89231c4]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
[aadc86e]18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24#include <ctype.h>
[3b9ec3f]25#include <errno.h>
[aadc86e]26#include <stdio.h>
[e05bdb8]27#include <string.h>
[aadc86e]28
29#include "cmdline.h"
[e05bdb8]30#include "filename.h"
[aadc86e]31
32/* It might be useful to be able to disable all long options on small
[3b9ec3f]33 * platforms like pre-386 DOS and perhaps some PDAs...
[aadc86e]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 *
[e05bdb8]43 * <short syntax>
[aadc86e]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
[3b9ec3f]61 */
[aadc86e]62
63static const char newline_tabs[] = "\n\t\t\t\t";
64
[3b9ec3f]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;
[acc20b1]72static const char *args_msg = NULL, *extra_msg = NULL;
[3b9ec3f]73
74static const char *argv0 = NULL;
[aadc86e]75
[3b9ec3f]76void
77cmdline_help(void)
[aadc86e]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)) {
[3b9ec3f]85         o = longopts + HLP_DECODELONG(opt);
[aadc86e]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   }
[e05bdb8]123   /* FIXME: translate */
[aadc86e]124   puts("      --help\t\t\tdisplay this help and exit\n"
125        "      --version\t\t\toutput version information and exit");
[acc20b1]126
127   if (extra_msg) {
128      putnl();
129      puts(extra_msg);
130   }
[aadc86e]131   exit(0);
132}
133
[3b9ec3f]134void
135cmdline_version(void)
[aadc86e]136{
137   printf("%s - "PACKAGE" "VERSION"\n", argv0);
138}
139
[3b9ec3f]140void
141cmdline_syntax(void)
142
[acc20b1]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   }
[3b9ec3f]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
[acc20b1]163void
164cmdline_set_syntax_message(const char *args, const char *extra)
165{
166   args_msg = args;
167   extra_msg = extra;
168}
169
[3b9ec3f]170int
171cmdline_int_arg(void)
[aadc86e]172{
[3b9ec3f]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();
[acc20b1]183      exit(1);
[3b9ec3f]184   } else if (*optarg == '\0' || *endptr != '\0') {
185      fprintf(stderr, "%s: argument `%s' not an integer\n", argv0, optarg);
186      cmdline_syntax();
[acc20b1]187      exit(1);
[3b9ec3f]188   }
189   
190   return result;
[aadc86e]191}
192
[acc20b1]193double
194cmdline_double_arg(void)
[aadc86e]195{
[acc20b1]196   double result;
[3b9ec3f]197   char *endptr;
[aadc86e]198   
[3b9ec3f]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();
[acc20b1]206      exit(1);
[3b9ec3f]207   } else if (*optarg == '\0' || *endptr != '\0') {
208      fprintf(stderr, "%s: argument `%s' not a number\n", argv0, optarg);
209      cmdline_syntax();
[acc20b1]210      exit(1);
[3b9ec3f]211   }
[aadc86e]212   
[3b9ec3f]213   return result;
214}
215
[acc20b1]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
[3b9ec3f]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);
[aadc86e]253
254   if (opt == EOF) {
[3b9ec3f]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      }
[aadc86e]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) */
[3b9ec3f]271      /* FIXME: set opterr to 0 so we can translate messages? */
272      cmdline_syntax();
[a93df0a]273      /* FIXME: translate */
274      fprintf(stderr, "Try `%s --help' for more information.\n", argv0);
[acc20b1]275      exit(1);
[aadc86e]276    case HLP_VERSION: /* --version */
[3b9ec3f]277      cmdline_version();
[aadc86e]278      exit(0);
279    case HLP_HELP: /* --help */
[3b9ec3f]280      cmdline_version();
281      cmdline_syntax();
[aadc86e]282      putchar('\n');
[3b9ec3f]283      cmdline_help();
[aadc86e]284      exit(0);
285   }
286   return opt;
287}
Note: See TracBrowser for help on using the repository browser.