File: getlopt.c

package info (click to toggle)
mp3asm 0.01-2
  • links: PTS
  • area: non-free
  • in suites: woody
  • size: 92 kB
  • ctags: 138
  • sloc: ansic: 1,126; makefile: 56
file content (140 lines) | stat: -rw-r--r-- 3,064 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 *   getlopt.c
 *
 *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
 *   Tue Apr  8 07:15:13 MET DST 1997
 */

#include <stdio.h>
#include "getlopt.h"

int loptind = 1;	/* index in argv[] */
int loptchr = 0;	/* index in argv[loptind] */
char *loptarg;		/* points to argument if present, else to option */

#if defined(ultrix) || defined(ULTRIX)
char *strdup (char *src)
{
	char *dest;

	if (!(dest = (char *) malloc(strlen(src)+1)))
		return (NULL);
	return (strcpy(dest, src));
}
#endif

const topt
*findopt (int islong, char *opt, const topt *opts)
{
	if (!opts)
		return (0);
	while (opts->lname || opts->sname) {
		if (islong) {
			if (!strcmp(opts->lname, opt))
				return (opts);
		}
		else
			if (opts->sname == *opt)
				return (opts);
		opts++;
	}
	return (0);
}

int performoption (int argc, char *argv[], const topt *opt)
{
	int result = GLO_CONTINUE;

	if (!(opt->flags & 1)) /* doesn't take argument */
		if (opt->var)
			if (opt->flags & 2) /* var is *char */
				*((char *) opt->var) = (char) opt->value;
			else
				*((int *) opt->var) = opt->value;
		else
			result = opt->value ? opt->value : opt->sname;
	else { /* requires argument */
		if (loptind >= argc)
			return (GLO_NOARG);
		loptarg = argv[loptind++]+loptchr;
		loptchr = 0;
		if (opt->var)
			if (opt->flags & 2) /* var is *char */
				*((char **) opt->var) = strdup(loptarg);
			else
				*((int *) opt->var) = atoi(loptarg);
		else
			result = opt->value ? opt->value : opt->sname;
	}
	if (opt->func)
		opt->func(loptarg);
	return (result);
}

int getsingleopt (int argc, char *argv[], const topt *opts)
{
	char *thisopt;
	const topt *opt;
	static char shortopt[2] = {0, 0};

	if (loptind >= argc)
		return (GLO_END);
	thisopt = argv[loptind];
	if (!loptchr) { /* start new option string */
		if (thisopt[0] != '-' || !thisopt[1]) /* no more options */
			return (GLO_END);
		if (thisopt[1] == '-') /* "--" */
			if (thisopt[2]) { /* long option */
				loptarg = thisopt+2;
				loptind++;
				if (!(opt = findopt(1, thisopt+2, opts)))
					return (GLO_UNKNOWN);
				else
					return (performoption(argc, argv, opt));
			}
			else { /* "--" == end of options */
				loptind++;
				return (GLO_END);
			}
		else /* start short option(s) */
			loptchr = 1;
	}
	shortopt[0] = thisopt[loptchr];
	loptarg = shortopt;
	opt = findopt(0, thisopt+(loptchr++), opts);
	if (!thisopt[loptchr]) {
		loptind++;
		loptchr = 0;
	}
	if (!opt)
		return (GLO_UNKNOWN);
	else
		return (performoption(argc, argv, opt));
}

int getlopt (int argc, char *argv[], const topt *opts)
{
	int result;
	
	while ((result = getsingleopt(argc, argv, opts)) == GLO_CONTINUE);
	return (result);
}

void parselopts (int argc, char *argv[], const topt *opts, char *progname)
{
	int result;

	while ((result = getlopt(argc, argv, opts)))
		switch (result) {
			case GLO_UNKNOWN:
				fprintf (stderr, "%s: Unknown option \"%s\".\n",
					progname, loptarg);
				exit (1);
			case GLO_NOARG:
				fprintf (stderr, "%s: Missing argument for option \"%s\".\n",
					progname, loptarg);
				exit (1);
		}
}

/* EOF */