4
4
* This file is licensed by the GPL version 2. Works owned by the
5
5
* Transmission project are granted a special exemption to clause 2(b)
6
* so that the bulk of its code can remain under the MIT license.
6
* so that the bulk of its code can remain under the MIT license.
7
7
* This exemption does not extend to derived works not owned by
8
8
* the Transmission project.
41
41
getopts_usage_line( const tr_option * opt,
42
int longWidth, int shortWidth, int argWidth )
44
46
const char * longName = opt->longName ? opt->longName : "";
45
47
const char * shortName = opt->shortName ? opt->shortName : "";
46
48
const char * arg = getArgName( opt );
47
50
printf( " -%-*s --%-*s %-*s %s\n", shortWidth, shortName,
54
57
maxWidth( const struct tr_option * o,
55
int * longWidth, int * shortWidth, int * argWidth )
60
65
*longWidth = MAX( *longWidth, (int)strlen( o->longName ) );
63
68
*shortWidth = MAX( *shortWidth, (int)strlen( o->shortName ) );
65
if(( arg = getArgName( o )))
70
if( ( arg = getArgName( o ) ) )
66
71
*argWidth = MAX( *argWidth, (int)strlen( arg ) );
70
tr_getopt_usage( const char * progName,
71
const char * description,
72
const struct tr_option opts[] )
75
tr_getopt_usage( const char * progName,
76
const char * description,
77
const struct tr_option opts[] )
77
struct tr_option help;
82
struct tr_option help;
78
83
const struct tr_option * o;
80
for( o=opts; o->val; ++o )
85
for( o = opts; o->val; ++o )
81
86
maxWidth( o, &longWidth, &shortWidth, &argWidth );
92
97
printf( description, progName );
93
98
printf( "\n\nOptions:\n" );
94
99
getopts_usage_line( &help, longWidth, shortWidth, argWidth );
95
for( o=opts; o->val; ++o )
100
for( o = opts; o->val; ++o )
96
101
getopts_usage_line( o, longWidth, shortWidth, argWidth );
99
104
static const tr_option *
100
findOption( const tr_option * opts,
102
const char ** setme_arg )
105
findOption( const tr_option * opts,
107
const char ** setme_arg )
105
const char * arg = NULL;
110
const char * arg = NULL;
106
111
const tr_option * o;
107
112
const tr_option * match = NULL;
109
114
/* find the longest matching option */
110
for( o=opts; o->val; ++o )
115
for( o = opts; o->val; ++o )
112
117
size_t len = o->longName ? strlen( o->longName ) : 0;
114
119
if( ( matchlen < len ) && !memcmp( str, "--", 2 )
115
&& !memcmp( str+2, o->longName, len )
116
&& ( str[len+2]=='\0' || ( o->has_arg && str[len+2]=='=' ) ) )
120
&& !memcmp( str + 2, o->longName, len )
121
&& ( str[len + 2] == '\0' || ( o->has_arg && str[len + 2] == '=' ) ) )
120
arg = str[len+2]=='=' ? str+len+3 : NULL;
125
arg = str[len + 2] == '=' ? str + len + 3 : NULL;
123
128
len = o->shortName ? strlen( o->shortName ) : 0;
125
130
if( ( matchlen < len ) && !memcmp( str, "-", 1 )
126
&& !memcmp( str+1, o->shortName, len )
127
&& ( str[len+1]=='\0' || o->has_arg ) )
131
&& !memcmp( str + 1, o->shortName, len )
132
&& ( str[len + 1] == '\0' || o->has_arg ) )
131
switch( str[len+1] ) {
132
case '\0': arg = NULL; break;
133
case '=': arg = str + len + 2; break;
134
default: arg = str + len + 1; break;
136
switch( str[len + 1] )
142
arg = str + len + 2; break;
145
arg = str + len + 1; break;
146
tr_getopt( const char * usage,
149
const tr_option * opts,
150
const char ** setme_optarg )
157
tr_getopt( const char * usage,
160
const tr_option * opts,
161
const char ** setme_optarg )
153
const char * arg = NULL;
164
const char * arg = NULL;
154
165
const tr_option * o = NULL;
156
*setme_optarg = NULL;
167
*setme_optarg = NULL;
158
169
/* handle the builtin 'help' option */
159
for( i=1; i<argc; ++i ) {
160
if( !strcmp(argv[i], "-h") || !strcmp(argv[i], "--help" ) ) {
170
for( i = 1; i < argc; ++i )
172
if( !strcmp( argv[i], "-h" ) || !strcmp( argv[i], "--help" ) )
161
174
tr_getopt_usage( argv[0], usage, opts );
166
179
/* out of options? */
167
if( argc==1 || tr_optind>=argc )
180
if( argc == 1 || tr_optind >= argc )
168
181
return TR_OPT_DONE;
170
183
o = findOption( opts, argv[tr_optind], &arg );
172
186
/* let the user know we got an unknown option... */
173
187
*setme_optarg = argv[tr_optind++];
174
188
return TR_OPT_UNK;
178
193
/* no argument needed for this option, so we're done */
180
195
return TR_OPT_ERR;
193
209
/* throw an error if the option needed an argument but didn't get one */
194
210
if( ++tr_optind >= argc )
195
211
return TR_OPT_ERR;
196
if( findOption( opts, argv[tr_optind], NULL ))
212
if( findOption( opts, argv[tr_optind], NULL ) )
197
213
return TR_OPT_ERR;
199
215
*setme_optarg = argv[tr_optind++];