source: git/src/cmdline.c @ 608e8b1

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 608e8b1 was d227ee5, checked in by Olly Betts <olly@…>, 25 years ago

Tidied up use of messages.

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