w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

shhopt.c
Go to the documentation of this file.
1 /* $Id: shhopt.c,v 1.5 1999/09/10 19:19:48 sverrehu Exp $ */
2 /*------------------------------------------------------------------------
3  | FILE shhopt.c
4  |
5  | DESCRIPTION Functions for parsing command line arguments. Values
6  | of miscellaneous types may be stored in variables,
7  | or passed to functions as specified.
8  |
9  | REQUIREMENTS Some systems lack the ANSI C -function strtoul. If your
10  | system is one of those, you'll ned to write one yourself,
11  | or get the GNU liberty-library (from prep.ai.mit.edu).
12  |
13  | WRITTEN BY Sverre H. Huseby <sverrehu@online.no>
14  +----------------------------------------------------------------------*/
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <ctype.h>
21 #include <limits.h>
22 #include <errno.h>
23 
24 #include "shhopt.h"
25 
26 /*-----------------------------------------------------------------------+
27 | PRIVATE DATA |
28 +-----------------------------------------------------------------------*/
29 
30 static void optFatalFunc(const char *, ...);
31 static void (*optFatal)(const char *format, ...) = optFatalFunc;
32 
33 /*-----------------------------------------------------------------------+
34 | PRIVATE FUNCTIONS |
35 +-----------------------------------------------------------------------*/
36 
37 /*------------------------------------------------------------------------
38  | NAME optFatalFunc
39  |
40  | FUNCTION Show given message and abort the program.
41  |
42  | INPUT format, ...
43  | Arguments used as with printf().
44  |
45  | RETURNS Never returns. The program is aborted.
46  */
47 char *rindex(char *s, int c)
48 {
49  char *back = NULL;
50  char *ptr;
51  ptr = s;
52  while(*ptr) {
53  if(*ptr == c) {
54  back = ptr;
55  }
56  ptr++;
57  }
58  return back;
59 }
60 
61 void
62 optFatalFunc(const char *format, ...)
63 {
64  va_list ap;
65 
66  fflush(stdout);
67  va_start(ap, format);
68  vfprintf(stderr, format, ap);
69  va_end(ap);
70  exit(99);
71 }
72 
73 /*------------------------------------------------------------------------
74  | NAME optStructCount
75  |
76  | FUNCTION Get number of options in a optStruct.
77  |
78  | INPUT opt array of possible options.
79  |
80  | RETURNS Number of options in the given array.
81  |
82  | DESCRIPTION Count elements in an optStruct-array. The strcture must
83  | be ended using an element of type OPT_END.
84  */
85 static int
87 {
88  int ret = 0;
89 
90  while (opt[ret].type != OPT_END)
91  ++ret;
92  return ret;
93 }
94 
95 /*------------------------------------------------------------------------
96  | NAME optMatch
97  |
98  | FUNCTION Find a matching option.
99  |
100  | INPUT opt array of possible options.
101  | s string to match, without `-' or `--'.
102  | lng match long option, otherwise short.
103  |
104  | RETURNS Index to the option if found, -1 if not found.
105  |
106  | DESCRIPTION Short options are matched from the first character in
107  | the given string.
108  */
109 static int
110 optMatch(optStruct opt[], const char *s, int lng)
111 {
112  int nopt, q, matchlen = 0;
113  const char *p;
114 
115  nopt = optStructCount(opt);
116  if (lng) {
117  if ((p = strchr(s, '=')) != NULL)
118  matchlen = p - s;
119  else
120  matchlen = strlen(s);
121  }
122  for (q = 0; q < nopt; q++) {
123  if (lng) {
124  if (!opt[q].longName)
125  continue;
126  if (strncmp(s, opt[q].longName, matchlen) == 0)
127  return q;
128  } else {
129  if (!opt[q].shortName)
130  continue;
131  if (*s == opt[q].shortName)
132  return q;
133  }
134  }
135  return -1;
136 }
137 
138 /*------------------------------------------------------------------------
139  | NAME optString
140  |
141  | FUNCTION Return a (static) string with the option name.
142  |
143  | INPUT opt the option to stringify.
144  | lng is it a long option?
145  |
146  | RETURNS Pointer to static string.
147  */
148 static char *
149 optString(optStruct *opt, int lng)
150 {
151  static char ret[31];
152 
153  if (lng) {
154  strcpy(ret, "--");
155  strncpy(ret + 2, opt->longName, 28);
156  } else {
157  ret[0] = '-';
158  ret[1] = opt->shortName;
159  ret[2] = '\0';
160  }
161  return ret;
162 }
163 
164 /*------------------------------------------------------------------------
165  | NAME optNeedsArgument
166  |
167  | FUNCTION Check if an option requires an argument.
168  |
169  | INPUT opt the option to check.
170  |
171  | RETURNS Boolean value.
172  */
173 static int
175 {
176  return opt->type == OPT_STRING
177  || opt->type == OPT_INT
178  || opt->type == OPT_UINT
179  || opt->type == OPT_LONG
180  || opt->type == OPT_ULONG;
181 }
182 
183 /*------------------------------------------------------------------------
184  | NAME argvRemove
185  |
186  | FUNCTION Remove an entry from an argv-array.
187  |
188  | INPUT argc pointer to number of options.
189  | argv array of option-/argument-strings.
190  | i index of option to remove.
191  |
192  | OUTPUT argc new argument count.
193  | argv array with given argument removed.
194  */
195 static void
196 argvRemove(int *argc, char *argv[], int i)
197 {
198  if (i >= *argc)
199  return;
200  while (i++ < *argc)
201  argv[i - 1] = argv[i];
202  --*argc;
203 }
204 
205 /*------------------------------------------------------------------------
206  | NAME optExecute
207  |
208  | FUNCTION Perform the action of an option.
209  |
210  | INPUT opt array of possible options.
211  | arg argument to option, if it applies.
212  | lng was the option given as a long option?
213  |
214  | RETURNS Nothing. Aborts in case of error.
215  */
216 void
217 optExecute(optStruct *opt, char *arg, int lng)
218 {
219  switch (opt->type) {
220  case OPT_FLAG:
221  if (opt->flags & OPT_CALLFUNC)
222  ((void (*)(void)) opt->arg)();
223  else
224  *((int *) opt->arg) = 1;
225  break;
226 
227  case OPT_STRING:
228  if (opt->flags & OPT_CALLFUNC)
229  ((void (*)(char *)) opt->arg)(arg);
230  else
231  *((char **) opt->arg) = arg;
232  break;
233 
234  case OPT_INT:
235  case OPT_LONG: {
236  long tmp;
237  char *e;
238 
239  tmp = strtol(arg, &e, 10);
240  if (*e)
241  optFatal("invalid number `%s'\n", arg);
242  if (errno == ERANGE
243  || (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN)))
244  optFatal("number `%s' to `%s' out of range\n",
245  arg, optString(opt, lng));
246  if (opt->type == OPT_INT) {
247  if (opt->flags & OPT_CALLFUNC)
248  ((void (*)(int)) opt->arg)((int) tmp);
249  else
250  *((int *) opt->arg) = (int) tmp;
251  } else /* OPT_LONG */ {
252  if (opt->flags & OPT_CALLFUNC)
253  ((void (*)(long)) opt->arg)(tmp);
254  else
255  *((long *) opt->arg) = tmp;
256  }
257  break;
258  }
259 
260  case OPT_UINT:
261  case OPT_ULONG: {
262  unsigned long tmp;
263  char *e;
264 
265  tmp = strtoul(arg, &e, 10);
266  if (*e)
267  optFatal("invalid number `%s'\n", arg);
268  if (errno == ERANGE
269  || (opt->type == OPT_UINT && tmp > UINT_MAX))
270  optFatal("number `%s' to `%s' out of range\n",
271  arg, optString(opt, lng));
272  if (opt->type == OPT_UINT) {
273  if (opt->flags & OPT_CALLFUNC)
274  ((void (*)(unsigned)) opt->arg)((unsigned) tmp);
275  else
276  *((unsigned *) opt->arg) = (unsigned) tmp;
277  } else /* OPT_ULONG */ {
278  if (opt->flags & OPT_CALLFUNC)
279  ((void (*)(unsigned long)) opt->arg)(tmp);
280  else
281  *((unsigned long *) opt->arg) = tmp;
282  }
283  break;
284  }
285 
286  default:
287  break;
288  }
289 }
290 
291 /*-----------------------------------------------------------------------+
292 | PUBLIC FUNCTIONS |
293 +-----------------------------------------------------------------------*/
294 
295 /*------------------------------------------------------------------------
296  | NAME optSetFatalFunc
297  |
298  | FUNCTION Set function used to display error message and exit.
299  |
300  | SYNOPSIS #include "shhopt.h"
301  | void optSetFatalFunc(void (*f)(const char *, ...));
302  |
303  | INPUT f function accepting printf()'like parameters,
304  | that _must_ abort the program.
305  */
306 void
307 optSetFatalFunc(void (*f)(const char *, ...))
308 {
309  optFatal = f;
310 }
311 
312 /*------------------------------------------------------------------------
313  | NAME optParseOptions
314  |
315  | FUNCTION Parse commandline options.
316  |
317  | SYNOPSIS #include "shhopt.h"
318  | void optParseOptions(int *argc, char *argv[],
319  | optStruct opt[], int allowNegNum);
320  |
321  | INPUT argc Pointer to number of options.
322  | argv Array of option-/argument-strings.
323  | opt Array of possible options.
324  | allowNegNum
325  | a negative number is not to be taken as
326  | an option.
327  |
328  | OUTPUT argc new argument count.
329  | argv array with arguments removed.
330  |
331  | RETURNS Nothing. Aborts in case of error.
332  |
333  | DESCRIPTION This function checks each option in the argv-array
334  | against strings in the opt-array, and `executes' any
335  | matching action. Any arguments to the options are
336  | extracted and stored in the variables or passed to
337  | functions pointed to by entries in opt.
338  |
339  | Options and arguments used are removed from the argv-
340  | array, and argc is decreased accordingly.
341  |
342  | Any error leads to program abortion.
343  */
344 void
345 optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
346 {
347  int ai, /* argv index. */
348  optarg, /* argv index of option argument, or -1 if none. */
349  mi, /* Match index in opt. */
350  done;
351  char *arg, /* Pointer to argument to an option. */
352  *o, /* pointer to an option character */
353  *p;
354 
355  /*
356  * Loop through all arguments.
357  */
358  for (ai = 0; ai < *argc; ) {
359  /*
360  * "--" indicates that the rest of the argv-array does not
361  * contain options.
362  */
363  if (strcmp(argv[ai], "--") == 0) {
364  argvRemove(argc, argv, ai);
365  break;
366  }
367 
368  if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) {
369  ++ai;
370  continue;
371  } else if (strncmp(argv[ai], "--", 2) == 0) {
372  /* long option */
373  /* find matching option */
374  if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0)
375  optFatal("unrecognized option `%s'\n", argv[ai]);
376 
377  /* possibly locate the argument to this option. */
378  arg = NULL;
379  if ((p = strchr(argv[ai], '=')) != NULL)
380  arg = p + 1;
381 
382  /* does this option take an argument? */
383  optarg = -1;
384  if (optNeedsArgument(&opt[mi])) {
385  /* option needs an argument. find it. */
386  if (!arg) {
387  if ((optarg = ai + 1) == *argc)
388  optFatal("option `%s' requires an argument\n",
389  optString(&opt[mi], 1));
390  arg = argv[optarg];
391  }
392  } else {
393  if (arg)
394  optFatal("option `%s' doesn't allow an argument\n",
395  optString(&opt[mi], 1));
396  }
397  /* perform the action of this option. */
398  optExecute(&opt[mi], arg, 1);
399  /* remove option and any argument from the argv-array. */
400  if (optarg >= 0)
401  argvRemove(argc, argv, ai);
402  argvRemove(argc, argv, ai);
403  } else if (*argv[ai] == '-') {
404  /* A dash by itself is not considered an option. */
405  if (argv[ai][1] == '\0') {
406  ++ai;
407  continue;
408  }
409  /* Short option(s) following */
410  o = argv[ai] + 1;
411  done = 0;
412  optarg = -1;
413  while (*o && !done) {
414  /* find matching option */
415  if ((mi = optMatch(opt, o, 0)) < 0)
416  optFatal("unrecognized option `-%c'\n", *o);
417 
418  /* does this option take an argument? */
419  optarg = -1;
420  arg = NULL;
421  if (optNeedsArgument(&opt[mi])) {
422  /* option needs an argument. find it. */
423  arg = o + 1;
424  if (!*arg) {
425  if ((optarg = ai + 1) == *argc)
426  optFatal("option `%s' requires an argument\n",
427  optString(&opt[mi], 0));
428  arg = argv[optarg];
429  }
430  done = 1;
431  }
432  /* perform the action of this option. */
433  optExecute(&opt[mi], arg, 0);
434  ++o;
435  }
436  /* remove option and any argument from the argv-array. */
437  if (optarg >= 0)
438  argvRemove(argc, argv, ai);
439  argvRemove(argc, argv, ai);
440  } else {
441  /* a non-option argument */
442  ++ai;
443  }
444  }
445 }
long __cdecl strtol(char const *_String, char **_EndPtr, int _Radix)
unsigned long __cdecl strtoul(char const *_String, char **_EndPtr, int _Radix)
q
Definition: afm2pl.c:2287
#define type(a)
Definition: aptex-macros.h:171
#define ap
#define fflush
Definition: xxstdio.h:24
char * strncpy()
int strcmp()
Definition: coll.cpp:143
char * strcpy()
static void
Definition: fpif.c:118
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
#define c(n)
Definition: gpos-common.c:150
#define strchr
Definition: gsftopk.c:59
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
char * optarg
Definition: getopt.c:42
int errno
#define INT_MIN
Definition: c-minmax.h:50
#define INT_MAX
Definition: c-minmax.h:53
#define UINT_MAX
Definition: c-minmax.h:56
static int ret
Definition: convert.c:72
int strncmp()
#define isdigit(c)
Definition: snprintf.c:177
static int format
Definition: pbmclean.c:15
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
ShellFileEnvironment e
Definition: sh6.c:388
void optSetFatalFunc(void(*f)(const char *,...))
Definition: shhopt.c:293
void optExecute(optStruct *opt, char *arg, int lng)
Definition: shhopt.c:203
void optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
Definition: shhopt.c:331
#define OPT_CALLFUNC
Definition: shhopt.h:21
@ OPT_LONG
Definition: shhopt.h:16
@ OPT_UINT
Definition: shhopt.h:15
@ OPT_ULONG
Definition: shhopt.h:17
@ OPT_END
Definition: shhopt.h:11
@ OPT_INT
Definition: shhopt.h:14
@ OPT_FLAG
Definition: shhopt.h:12
@ OPT_STRING
Definition: shhopt.h:13
void * arg
Definition: shhopt.h:27
char * longName
Definition: shhopt.h:25
optArgType type
Definition: shhopt.h:26
int flags
Definition: shhopt.h:29
char shortName
Definition: shhopt.h:24
*job_name strlen((char *) job_name) - 4)
back
Definition: tex4ht.c:3533
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
#define va_start(pvar)
Definition: varargs.h:30
#define va_end(pvar)
Definition: varargs.h:38
char * va_list
Definition: varargs.h:22
static void argvRemove(int *argc, char *argv[], int i)
Definition: shhopt.c:196
static char * optString(optStruct *opt, int lng)
Definition: shhopt.c:149
static int optStructCount(optStruct opt[])
Definition: shhopt.c:86
static int optMatch(optStruct opt[], const char *s, int lng)
Definition: shhopt.c:110
char * rindex(char *s, int c)
Definition: shhopt.c:47
static int optNeedsArgument(optStruct *opt)
Definition: shhopt.c:174
static void optFatalFunc(const char *,...)
Definition: shhopt.c:62
static void(* optFatal)(const char *format,...)
Definition: shhopt.c:31
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269