source: trunk/daemon/getopts.c @ 6294

Last change on this file since 6294 was 6294, checked in by charles, 14 years ago

(daemon) allow wildcards to be used when adding torrents again, such as "transmission-remote -a ~/Desktop/*torrent"

File size: 6.6 KB
Line 
1/* getopts.c - Command line argument parser
2 *
3 * Whom: Steve Mertz <steve@dragon-ware.com>
4 * Date: 20010111
5 * Why:  Because I couldn't find one that I liked. So I wrote this one.
6 *
7*/
8/*
9 * Copyright (c) 2001-2004 Steve Mertz <steve@dragon-ware.com>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice, this
16 * list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * Neither the name of Dragon Ware nor the names of its contributors may be
23 * used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS
30 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38*/
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43#include "getopts.h"
44
45#ifndef MAX
46#define MAX(a,b) (((a) > (b)) ? (a) : (b))
47#endif
48
49int option_index = 1;
50
51static const char*
52getArgName( const struct options * opt )
53{
54    if( !opt->args )   return "";
55    if( opt->argName ) return opt->argName;
56    return "<args>";
57}
58
59static void
60getopts_usage_line( const struct options * opt, int nameWidth, int shortWidth, int argWidth )
61{
62    const char * name       = opt->name ? opt->name : "";
63    const char * shortName  = opt->shortName ? opt->shortName : "";
64    const char * arg        = getArgName( opt );
65    printf( "  -%*s, --%-*s %-*s  %s\n", shortWidth, shortName, nameWidth, name, argWidth, arg, opt->description );
66}
67
68/* int getopts_usage()
69 *
70 *  Returns: 1 - Successful
71 */
72int getopts_usage(const char *progName, const char *usage, struct options opts[])
73{
74  int count;
75  int nameWidth = 0;
76  int shortWidth = 0;
77  int argWidth = 0;
78  struct options help;
79
80  for( count=0; opts[count].description; ++count )
81  {
82    const char * arg;
83
84    if( opts[count].name ) 
85      nameWidth = MAX( nameWidth, (int)strlen( opts[count].name ) );
86
87    if( opts[count].shortName )
88      shortWidth = MAX( shortWidth, (int)strlen( opts[count].shortName ) );
89
90    if(( arg = getArgName( &opts[count] )))
91      argWidth = MAX( argWidth, (int)strlen( arg ) );
92  }
93
94  if( !usage )
95    usage = "Usage: %s [options]";
96  printf( usage, progName );
97  printf( "\n\n" );
98  printf( "Usage:\n" );
99
100  help.number = -1;
101  help.name = "help";
102  help.description = "Display this help page and exit";
103  help.shortName = "h";
104  help.args = 0;
105  getopts_usage_line( &help, nameWidth, shortWidth, argWidth );
106 
107  for( count=0; opts[count].description; ++count )
108      getopts_usage_line( &opts[count], nameWidth, shortWidth, argWidth );
109
110  return 1;
111}
112
113/* int getopts()
114 *
115 * Returns: -1 - Couldn't allocate memory.  Please handle me.
116 *          0  - No arguements to parse
117 *          #  - The number in the struct for the matched arg.
118 *
119*/
120int
121getopts( const char      * usage,
122         int               argc,
123         char           ** argv,
124         struct options  * opts,
125         char           ** args )
126{
127  int argCounter, sizeOfArgs;
128  if (argc == 1 || option_index == argc)
129    return 0;
130 
131/* Search for '-h' or '--help' first.  Then we can just exit */
132  for (argCounter = 1; argCounter < argc; argCounter++)
133    {
134      if (!strcmp(argv[argCounter], "-h") || !strcmp(argv[argCounter], "--help"))
135        {
136useage:
137fprintf( stderr, "dkdkdkdkdkd\n" );
138          getopts_usage(argv[0], usage, opts);
139          exit(0);
140        }
141    }
142/* End of -h --help section */
143 
144  *args = NULL;
145  if (option_index <= argc)
146    {
147      for (argCounter = 0; opts[argCounter].number!=0; argCounter++)
148        {
149          if ((opts[argCounter].name && !strcmp(opts[argCounter].name, (argv[option_index]+2))) || 
150              (opts[argCounter].shortName && !strcmp(opts[argCounter].shortName, (argv[option_index]+1))))
151            {
152              if (opts[argCounter].args)
153                {
154                  option_index++;
155                  if (option_index >= argc)
156                    goto useage;
157/* This grossness that follows is to support having a '-' in the argument.  */
158                  if (*argv[option_index] == '-')
159                    {
160                      int optionSeeker;
161                      for (optionSeeker = 0; opts[optionSeeker].description; optionSeeker++)
162                        {
163                          if ((opts[optionSeeker].name && 
164                               !strcmp(opts[optionSeeker].name, (argv[option_index]+2))) ||
165                               (opts[optionSeeker].shortName && 
166                               !strcmp(opts[optionSeeker].shortName, (argv[option_index]+1))))
167                            {
168                              goto useage;
169                            }
170                        }
171/* End of gross hack for supporting '-' in arguments. */
172                    }
173                  sizeOfArgs = strlen(argv[option_index]);
174#ifdef __cplusplus
175                  if ((*args = (char *)calloc(1, sizeOfArgs+1)) == NULL)
176#else
177                  if ((*args = calloc(1, sizeOfArgs+1)) == NULL)
178#endif
179                    return -1;
180                  strncpy(*args, argv[option_index], sizeOfArgs);
181                }
182              option_index++;
183              return opts[argCounter].number;
184            }
185        }
186/** The Option doesn't exist.  We should warn them. */
187      //if (*argv[option_index] == '-')
188        {
189          sizeOfArgs = strlen(argv[option_index]);
190#ifdef __cplusplus
191          if ((*args = (char *)calloc(1, sizeOfArgs+1)) == NULL)
192#else
193          if ((*args = calloc(1, sizeOfArgs+1)) == NULL)
194#endif
195            return -1;
196          strncpy(*args, argv[option_index], sizeOfArgs);
197          option_index++;
198          return -2;
199        }
200    }
201  return 0;
202}
203
204
205
206
207
208
Note: See TracBrowser for help on using the repository browser.