source: git/src/cmdline.c @ 749fd1e

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 749fd1e was cb3d1e2, checked in by Olly Betts <olly@…>, 24 years ago

Trimmed trailing whitespace from source files; updates BUGS, NEWS, TODO;
Added manifest constants for all leg flags.

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