source: git/src/cmdline.c @ 175cac6

RELEASE/1.2debug-cidebug-ci-sanitisersstereowalls-data
Last change on this file since 175cac6 was 175cac6, checked in by Olly Betts <olly@…>, 14 years ago

src/cmdline.c: Remove reference to MSDOS.

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

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[6974a34]1/* cmdline.c
[aadc86e]2 * Wrapper for GNU getopt which deals with standard options
[0580c6a]3 * Copyright (C) 1998-2001,2003,2004 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
[ecbc6c18]17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  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
[be97baf]31#include "getopt.h"
32
[aadc86e]33#include "cmdline.h"
[e05bdb8]34#include "filename.h"
[aadc86e]35
[d227ee5]36#include "message.h"
37
[aadc86e]38/* It might be useful to be able to disable all long options on small
[175cac6]39 * platforms like older PDAs.
[aadc86e]40 */
41#if 0
42# define getopt_long(ARGC, ARGV, STR, OPTS, PTR) getopt(ARGC, ARGV, STR)
43#endif
44
45/*
46 * bad command line give:
47 * <problem>
[cb3d1e2]48 *
[e05bdb8]49 * <short syntax>
[cb3d1e2]50 *
[aadc86e]51 * --help gives:
52 * <version>
[cb3d1e2]53 *
[aadc86e]54 * <short syntax>
55 *
56 * <table>
[cb3d1e2]57 *
[aadc86e]58 * <blurb>
59 *
60 * --version gives:
61 * <version>
62 */
63
64/*
65 * want to cope with optional/required parameters on long options
66 * and also parameters on short options
[3b9ec3f]67 */
[aadc86e]68
69static const char newline_tabs[] = "\n\t\t\t\t";
70
[3b9ec3f]71static int argc;
[647407d]72static char * const *argv;
[3b9ec3f]73static const char *shortopts;
74static const struct option *longopts;
75static int *longind;
76static const struct help_msg *help;
77static int min_args, max_args;
[acc20b1]78static const char *args_msg = NULL, *extra_msg = NULL;
[3b9ec3f]79
80void
81cmdline_help(void)
[aadc86e]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)) {
[3b9ec3f]89         o = longopts + HLP_DECODELONG(opt);
[aadc86e]90         longopt = o->name;
91         opt = o->val;
92      }
93
[0580c6a]94      if (isalnum((unsigned char)opt))
[5fbfd8d]95         printf("  -%c%c", opt, longopt ? ',' : ' ');
[aadc86e]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   }
[a580dc1]127   printf("      --help\t\t\t%s\n", msg(/*display this help and exit*/150));
128   printf("      --version\t\t\t%s\n", msg(/*output version information and exit*/151));
[acc20b1]129
130   if (extra_msg) {
131      putnl();
132      puts(extra_msg);
133   }
[647407d]134
[aadc86e]135   exit(0);
136}
137
[3b9ec3f]138void
139cmdline_version(void)
[aadc86e]140{
[82afbc4]141   printf("%s - "PRETTYPACKAGE" "VERSION"\n", msg_appname());
[aadc86e]142}
143
[3b9ec3f]144void
145cmdline_syntax(void)
[cb3d1e2]146{
[bdfe97f]147   printf("\n%s: %s", msg(/*Syntax*/49), msg_appname());
[a580dc1]148   if (help->opt) printf(" [%s]...", msg(/*OPTION*/153));
[acc20b1]149   if (args_msg) {
150      putchar(' ');
151      puts(args_msg);
152      return;
153   }
[3b9ec3f]154   if (min_args) {
155      int i = min_args;
[a580dc1]156      while (i--) printf(" %s", msg(/*FILE*/124));
[3b9ec3f]157   }
[647407d]158   if (max_args == -1) {
[a580dc1]159      if (!min_args) printf(" [%s]", msg(/*FILE*/124));
[647407d]160      fputs("...", stdout);
161   } else if (max_args > min_args) {
162      int i = max_args - min_args;
[a580dc1]163      while (i--) printf(" [%s]", msg(/*FILE*/124));
[647407d]164   }
[3b9ec3f]165   putnl();
166}
167
[2668614]168static void
169syntax_and_help_pointer(void)
170{
171   cmdline_syntax();
[c40038a]172   fprintf(stderr, msg(/*Try `%s --help' for more information.&#10;*/157),
[2668614]173           msg_appname());
174   exit(1);
175}
176
177static void
178moan_and_die(int msgno)
179{
180   fprintf(stderr, "%s: ", msg_appname());
181   fprintf(stderr, msg(msgno), optarg);
182   fputnl(stderr);
183   cmdline_syntax();
184   exit(1);
185}
186
187void
188cmdline_too_few_args(void)
189{
190   fprintf(stderr, "%s: %s\n", msg_appname(), msg(/*too few arguments*/122));
191   syntax_and_help_pointer();
192}
193
194void
195cmdline_too_many_args(void)
196{
197   fprintf(stderr, "%s: %s\n", msg_appname(), msg(/*too many arguments*/123));
198   syntax_and_help_pointer();
199}
200
[acc20b1]201void
202cmdline_set_syntax_message(const char *args, const char *extra)
203{
204   args_msg = args;
205   extra_msg = extra;
206}
207
[3b9ec3f]208int
209cmdline_int_arg(void)
[aadc86e]210{
[f2122f0]211   long result;
[3b9ec3f]212   char *endptr;
[cb3d1e2]213
[3b9ec3f]214   errno = 0;
215
216   result = strtol(optarg, &endptr, 10);
217
[f2122f0]218   if (errno == ERANGE || result > INT_MAX || result < INT_MIN) {
[2668614]219      moan_and_die(/*numeric argument `%s' out of range*/185);
[3b9ec3f]220   } else if (*optarg == '\0' || *endptr != '\0') {
[2668614]221      moan_and_die(/*argument `%s' not an integer*/186);
[3b9ec3f]222   }
[cb3d1e2]223
[f2122f0]224   return (int)result;
[aadc86e]225}
226
[acc20b1]227double
228cmdline_double_arg(void)
[aadc86e]229{
[acc20b1]230   double result;
[3b9ec3f]231   char *endptr;
[cb3d1e2]232
[3b9ec3f]233   errno = 0;
234
235   result = strtod(optarg, &endptr);
236
237   if (errno == ERANGE) {
[2668614]238      moan_and_die(/*numeric argument `%s' out of range*/185);
[3b9ec3f]239   } else if (*optarg == '\0' || *endptr != '\0') {
[2668614]240      moan_and_die(/*argument `%s' not a number*/187);
[3b9ec3f]241   }
[cb3d1e2]242
[3b9ec3f]243   return result;
244}
245
246void
247cmdline_init(int argc_, char *const *argv_, const char *shortopts_,
248             const struct option *longopts_, int *longind_,
249             const struct help_msg *help_,
250             int min_args_, int max_args_)
251{
252   argc = argc_;
253   argv = argv_;
254   shortopts = shortopts_;
255   longopts = longopts_;
256   longind = longind_;
257   help = help_;
258   min_args = min_args_;
259   max_args = max_args_;
260}
261
262int
263cmdline_getopt(void)
264{
265   int opt = getopt_long(argc, argv, shortopts, longopts, longind);
[aadc86e]266
[2668614]267   switch (opt) {
268    case EOF:
[a580dc1]269      /* check valid # of args given - if not give syntax message */
[3b9ec3f]270      if (argc - optind < min_args) {
[2668614]271         cmdline_too_few_args();
[3b9ec3f]272      } else if (max_args >= 0 && argc - optind > max_args) {
[2668614]273         cmdline_too_many_args();
[3b9ec3f]274      }
[2668614]275      break;
[aadc86e]276    case ':': /* parameter missing */
277    case '?': /* unknown opt, ambiguous match, or extraneous param */
[a580dc1]278      /* getopt displays a message for us */
[2668614]279      syntax_and_help_pointer();
280      break;
[aadc86e]281    case HLP_VERSION: /* --version */
[3b9ec3f]282      cmdline_version();
[aadc86e]283      exit(0);
284    case HLP_HELP: /* --help */
[3b9ec3f]285      cmdline_version();
286      cmdline_syntax();
[aadc86e]287      putchar('\n');
[3b9ec3f]288      cmdline_help();
[aadc86e]289      exit(0);
290   }
291   return opt;
292}
Note: See TracBrowser for help on using the repository browser.