~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to getopt/getopt.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
    getopt.c - Enhanced implementation of BSD getopt(1)
3
 
    Copyright (c) 1997-2005 Frodo Looijaard <frodo@frodo.looijaard.name>
4
 
 
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.
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
12
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
    GNU General Public License for more details.
14
 
 
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
17
 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
*/
 
2
 *  getopt.c - Enhanced implementation of BSD getopt(1)
 
3
 *  Copyright (c) 1997-2005 Frodo Looijaard <frodo@frodo.looijaard.name>
 
4
 *
 
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.
 
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
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
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
 
17
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 */
19
19
 
20
20
/* 
21
21
 * Version 1.0-b4: Tue Sep 23 1997. First public release.
39
39
 *   Fixed a few type's in the manpage
40
40
 */
41
41
 
 
42
/* Exit codes:
 
43
 *   0) No errors, succesful operation.
 
44
 *   1) getopt(3) returned an error.
 
45
 *   2) A problem with parameter parsing for getopt(1).
 
46
 *   3) Internal error, out of memory
 
47
 *   4) Returned for -T
 
48
 */
 
49
#define GETOPT_EXIT_CODE        1
 
50
#define PARAMETER_EXIT_CODE     2
 
51
#define XALLOC_EXIT_CODE        3
 
52
#define TEST_EXIT_CODE          4
 
53
 
42
54
#include <stdio.h>
43
55
#include <stdlib.h>
44
56
#include <string.h>
47
59
#include <getopt.h>
48
60
 
49
61
#include "nls.h"
 
62
#include "xalloc.h"
50
63
 
51
64
/* NON_OPT is the code that is returned when a non-option is found in '+' 
52
 
   mode */
 
65
 * mode */
53
66
#define NON_OPT 1
54
67
/* LONG_OPT is the code that is returned when a long option is found. */
55
68
#define LONG_OPT 2
56
69
 
57
70
/* The shells recognized. */
58
 
typedef enum {BASH,TCSH} shell_t;
 
71
typedef enum { BASH, TCSH } shell_t;
59
72
 
60
73
 
61
74
/* Some global variables that tells us how to parse. */
62
 
shell_t shell=BASH; /* The shell we generate output for. */
63
 
int quiet_errors=0; /* 0 is not quiet. */
64
 
int quiet_output=0; /* 0 is not quiet. */
65
 
int quote=1; /* 1 is do quote. */
66
 
int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
 
75
static shell_t shell = BASH;    /* The shell we generate output for. */
 
76
static int quiet_errors = 0;    /* 0 is not quiet. */
 
77
static int quiet_output = 0;    /* 0 is not quiet. */
 
78
static int quote = 1;           /* 1 is do quote. */
 
79
 
 
80
/* Allow changing which getopt is in use with function pointer */
 
81
int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
 
82
                       const struct option * longopts, int *longindex);
67
83
 
68
84
/* Function prototypes */
69
 
void *our_malloc(size_t size);
70
 
void *our_realloc(void *ptr, size_t size);
71
 
const char *normalize(const char *arg);
72
 
int generate_output(char * argv[],int argc,const char *optstr,
73
 
                    const struct option *longopts);
 
85
static const char *normalize(const char *arg);
 
86
static int generate_output(char *argv[], int argc, const char *optstr,
 
87
                           const struct option *longopts);
74
88
int main(int argc, char *argv[]);
75
 
void parse_error(const char *message);
76
 
void add_long_options(char *options);
77
 
void add_longopt(const char *name,int has_arg);
78
 
void print_help(void);
79
 
void set_shell(const char *new_shell);
80
 
void set_initial_shell(void);
81
 
 
82
 
void *our_malloc(size_t size)
83
 
{
84
 
        void *ret=malloc(size);
85
 
        if (! ret) {
86
 
                fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
87
 
                exit(3);
88
 
        }
89
 
        return(ret);
90
 
}
91
 
 
92
 
void *our_realloc(void *ptr, size_t size)
93
 
{
94
 
        void *ret=realloc(ptr,size);
95
 
        if (! ret && size) {
96
 
                fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
97
 
                exit(3);
98
 
        }
99
 
        return(ret);
100
 
}
 
89
static void parse_error(const char *message);
 
90
static void add_long_options(char *options);
 
91
static void add_longopt(const char *name, int has_arg);
 
92
static void print_help(void);
 
93
static void set_shell(const char *new_shell);
101
94
 
102
95
/*
103
 
 * This function 'normalizes' a single argument: it puts single quotes around
104
 
 * it and escapes other special characters. If quote is false, it just
105
 
 * returns its argument.
 
96
 * This function 'normalizes' a single argument: it puts single quotes
 
97
 * around it and escapes other special characters. If quote is false, it
 
98
 * just returns its argument.
 
99
 *
106
100
 * Bash only needs special treatment for single quotes; tcsh also recognizes
107
 
 * exclamation marks within single quotes, and nukes whitespace.
108
 
 * This function returns a pointer to a buffer that is overwritten by 
109
 
 * each call.
 
101
 * exclamation marks within single quotes, and nukes whitespace. This
 
102
 * function returns a pointer to a buffer that is overwritten by each call.
110
103
 */
111
 
const char *normalize(const char *arg)
 
104
static const char *normalize(const char *arg)
112
105
{
113
 
        static char *BUFFER=NULL;
114
 
        const char *argptr=arg;
 
106
        static char *BUFFER = NULL;
 
107
        const char *argptr = arg;
115
108
        char *bufptr;
116
109
 
117
 
        free(BUFFER);
118
 
 
119
 
        if (!quote) { /* Just copy arg */
120
 
                BUFFER=our_malloc(strlen(arg)+1);
121
 
                        
122
 
                strcpy(BUFFER,arg);
 
110
        if (!quote) {
 
111
                /* Just copy arg */
 
112
                BUFFER = xmalloc(strlen(arg) + 1);
 
113
                strcpy(BUFFER, arg);
123
114
                return BUFFER;
124
115
        }
125
116
 
126
 
        /* Each character in arg may take upto four characters in the result:
127
 
           For a quote we need a closing quote, a backslash, a quote and an
128
 
           opening quote! We need also the global opening and closing quote,
129
 
           and one extra character for '\0'. */
130
 
        BUFFER=our_malloc(strlen(arg)*4+3);
 
117
        /*
 
118
         * Each character in arg may take upto four characters in the
 
119
         * result: For a quote we need a closing quote, a backslash, a quote
 
120
         * and an opening quote! We need also the global opening and closing
 
121
         * quote, and one extra character for '\0'.
 
122
         */
 
123
        BUFFER = xmalloc(strlen(arg) * 4 + 3);
131
124
 
132
 
        bufptr=BUFFER;
133
 
        *bufptr++='\'';
 
125
        bufptr = BUFFER;
 
126
        *bufptr++ = '\'';
134
127
 
135
128
        while (*argptr) {
136
129
                if (*argptr == '\'') {
137
130
                        /* Quote: replace it with: '\'' */
138
 
                        *bufptr++='\'';
139
 
                        *bufptr++='\\';
140
 
                        *bufptr++='\'';
141
 
                        *bufptr++='\'';
142
 
                } else if (shell==TCSH && *argptr=='!') {
 
131
                        *bufptr++ = '\'';
 
132
                        *bufptr++ = '\\';
 
133
                        *bufptr++ = '\'';
 
134
                        *bufptr++ = '\'';
 
135
                } else if (shell == TCSH && *argptr == '!') {
143
136
                        /* Exclamation mark: replace it with: \! */
144
 
                        *bufptr++='\'';
145
 
                        *bufptr++='\\';
146
 
                        *bufptr++='!';
147
 
                        *bufptr++='\'';
148
 
                } else if (shell==TCSH && *argptr=='\n') {
 
137
                        *bufptr++ = '\'';
 
138
                        *bufptr++ = '\\';
 
139
                        *bufptr++ = '!';
 
140
                        *bufptr++ = '\'';
 
141
                } else if (shell == TCSH && *argptr == '\n') {
149
142
                        /* Newline: replace it with: \n */
150
 
                        *bufptr++='\\';
151
 
                        *bufptr++='n';
152
 
                } else if (shell==TCSH && isspace(*argptr)) {
 
143
                        *bufptr++ = '\\';
 
144
                        *bufptr++ = 'n';
 
145
                } else if (shell == TCSH && isspace(*argptr)) {
153
146
                        /* Non-newline whitespace: replace it with \<ws> */
154
 
                        *bufptr++='\'';
155
 
                        *bufptr++='\\';
156
 
                        *bufptr++=*argptr;
157
 
                        *bufptr++='\'';
 
147
                        *bufptr++ = '\'';
 
148
                        *bufptr++ = '\\';
 
149
                        *bufptr++ = *argptr;
 
150
                        *bufptr++ = '\'';
158
151
                } else
159
152
                        /* Just copy */
160
 
                        *bufptr++=*argptr;
 
153
                        *bufptr++ = *argptr;
161
154
                argptr++;
162
155
        }
163
 
        *bufptr++='\'';
164
 
        *bufptr++='\0';
 
156
        *bufptr++ = '\'';
 
157
        *bufptr++ = '\0';
165
158
        return BUFFER;
166
159
}
167
160
 
172
165
 * optstr must contain the short options, and longopts the long options.
173
166
 * Other settings are found in global variables.
174
167
 */
175
 
int generate_output(char * argv[],int argc,const char *optstr,
176
 
                    const struct option *longopts)
 
168
static int generate_output(char *argv[], int argc, const char *optstr,
 
169
                           const struct option *longopts)
177
170
{
178
 
        int exit_code = 0; /* We assume everything will be OK */
 
171
        int exit_code = EXIT_SUCCESS;   /* Assume everything will be OK */
179
172
        int opt;
180
173
        int longindex;
181
174
        const char *charptr;
182
175
 
183
 
        if (quiet_errors) /* No error reporting from getopt(3) */
184
 
                opterr=0;
185
 
        optind=0; /* Reset getopt(3) */
 
176
        if (quiet_errors)
 
177
                /* No error reporting from getopt(3) */
 
178
                opterr = 0;
 
179
        /* Reset getopt(3) */
 
180
        optind = 0;
186
181
 
187
 
        while ((opt = (alternative?
188
 
                      getopt_long_only(argc,argv,optstr,longopts,&longindex):
189
 
                      getopt_long(argc,argv,optstr,longopts,&longindex))) 
190
 
               != EOF) 
191
 
                if (opt == '?' || opt == ':' )
192
 
                        exit_code = 1;
193
 
                else if (!quiet_output) 
194
 
                {
 
182
        while ((opt =
 
183
                (getopt_long_fp(argc, argv, optstr, longopts, &longindex)))
 
184
               != EOF)
 
185
                if (opt == '?' || opt == ':')
 
186
                        exit_code = GETOPT_EXIT_CODE;
 
187
                else if (!quiet_output) {
195
188
                        if (opt == LONG_OPT) {
196
 
                                printf(" --%s",longopts[longindex].name);
197
 
                                if (longopts[longindex].has_arg) 
198
 
                                        printf(" %s",
199
 
                                               normalize(optarg?optarg:""));
200
 
                        } else if (opt == NON_OPT) 
201
 
                                printf(" %s",normalize(optarg)); 
 
189
                                printf(" --%s", longopts[longindex].name);
 
190
                                if (longopts[longindex].has_arg)
 
191
                                        printf(" %s", normalize(optarg ? optarg : ""));
 
192
                        } else if (opt == NON_OPT)
 
193
                                printf(" %s", normalize(optarg));
202
194
                        else {
203
 
                                printf(" -%c",opt);
204
 
                                charptr = strchr(optstr,opt);
 
195
                                printf(" -%c", opt);
 
196
                                charptr = strchr(optstr, opt);
205
197
                                if (charptr != NULL && *++charptr == ':')
206
 
                                        printf(" %s",
207
 
                                               normalize(optarg?optarg:""));
 
198
                                        printf(" %s", normalize(optarg ? optarg : ""));
208
199
                        }
209
200
                }
210
 
        
211
 
        if (! quiet_output) {
 
201
 
 
202
        if (!quiet_output) {
212
203
                printf(" --");
213
 
                while (optind < argc) 
214
 
                        printf(" %s",normalize(argv[optind++]));
 
204
                while (optind < argc)
 
205
                        printf(" %s", normalize(argv[optind++]));
215
206
                printf("\n");
216
207
        }
217
208
        return exit_code;
218
209
}
219
210
 
220
211
/*
221
 
 * Report an error when parsing getopt's own arguments.
222
 
 * If message is NULL, we already sent a message, we just exit with a helpful
223
 
 * hint.
 
212
 * Report an error when parsing getopt's own arguments. If message is NULL,
 
213
 * we already sent a message, we just exit with a helpful hint.
224
214
 */
225
 
void parse_error(const char *message)
 
215
static void __attribute__ ((__noreturn__)) parse_error(const char *message)
226
216
{
227
217
        if (message)
228
 
                fprintf(stderr,"getopt: %s\n",message);
229
 
        fputs(_("Try `getopt --help' for more information.\n"),stderr);
230
 
        exit(2);
 
218
                warnx("%s", message);
 
219
        fprintf(stderr, _("Try `%s --help' for more information.\n"),
 
220
                program_invocation_short_name);
 
221
        exit(PARAMETER_EXIT_CODE);
231
222
}
232
223
 
233
 
static struct option *long_options=NULL;
234
 
static int long_options_length=0; /* Length of array */
235
 
static int long_options_nr=0; /* Nr of used elements in array */
 
224
static struct option *long_options = NULL;
 
225
static int long_options_length = 0;     /* Length of array */
 
226
static int long_options_nr = 0;         /* Nr of used elements in array */
236
227
#define LONG_OPTIONS_INCR 10
237
228
#define init_longopt() add_longopt(NULL,0)
238
229
 
239
230
/* Register a long option. The contents of name is copied. */
240
 
void add_longopt(const char *name,int has_arg)
 
231
static void add_longopt(const char *name, int has_arg)
241
232
{
242
233
        char *tmp;
243
 
        if (!name) { /* init */
 
234
        if (!name) {
 
235
                /* init */
244
236
                free(long_options);
245
 
                long_options=NULL;
246
 
                long_options_length=0;
247
 
                long_options_nr=0;
 
237
                long_options = NULL;
 
238
                long_options_length = 0;
 
239
                long_options_nr = 0;
248
240
        }
249
241
 
250
242
        if (long_options_nr == long_options_length) {
251
243
                long_options_length += LONG_OPTIONS_INCR;
252
 
                long_options=our_realloc(long_options,
253
 
                                         sizeof(struct option) * 
254
 
                                           long_options_length);
 
244
                long_options = xrealloc(long_options,
 
245
                                        sizeof(struct option) *
 
246
                                        long_options_length);
255
247
        }
256
248
 
257
 
        long_options[long_options_nr].name=NULL;
258
 
        long_options[long_options_nr].has_arg=0;
259
 
        long_options[long_options_nr].flag=NULL;
260
 
        long_options[long_options_nr].val=0;
 
249
        long_options[long_options_nr].name = NULL;
 
250
        long_options[long_options_nr].has_arg = 0;
 
251
        long_options[long_options_nr].flag = NULL;
 
252
        long_options[long_options_nr].val = 0;
261
253
 
262
 
        if (long_options_nr) { /* Not for init! */
263
 
                long_options[long_options_nr-1].has_arg=has_arg;
264
 
                long_options[long_options_nr-1].flag=NULL;
265
 
                long_options[long_options_nr-1].val=LONG_OPT;
266
 
                tmp = our_malloc(strlen(name)+1);
267
 
                strcpy(tmp,name);
268
 
                long_options[long_options_nr-1].name=tmp;
 
254
        if (long_options_nr) {
 
255
                /* Not for init! */
 
256
                long_options[long_options_nr - 1].has_arg = has_arg;
 
257
                long_options[long_options_nr - 1].flag = NULL;
 
258
                long_options[long_options_nr - 1].val = LONG_OPT;
 
259
                tmp = xmalloc(strlen(name) + 1);
 
260
                strcpy(tmp, name);
 
261
                long_options[long_options_nr - 1].name = tmp;
269
262
        }
270
263
        long_options_nr++;
271
264
}
272
 
        
 
265
 
273
266
 
274
267
/* 
275
 
 * Register several long options. options is a string of long options, 
276
 
 * separated by commas or whitespace. 
277
 
 * This nukes options! 
 
268
 * Register several long options. options is a string of long options,
 
269
 * separated by commas or whitespace. This nukes options!
278
270
 */
279
 
void add_long_options(char *options)
 
271
static void add_long_options(char *options)
280
272
{
281
273
        int arg_opt;
282
 
        char *tokptr=strtok(options,", \t\n");
 
274
        char *tokptr = strtok(options, ", \t\n");
283
275
        while (tokptr) {
284
 
                arg_opt=no_argument;
 
276
                arg_opt = no_argument;
285
277
                if (strlen(tokptr) > 0) {
286
 
                        if (tokptr[strlen(tokptr)-1] == ':') {
287
 
                                if (tokptr[strlen(tokptr)-2] == ':') {
288
 
                                        tokptr[strlen(tokptr)-2]='\0';
289
 
                                        arg_opt=optional_argument;
 
278
                        if (tokptr[strlen(tokptr) - 1] == ':') {
 
279
                                if (tokptr[strlen(tokptr) - 2] == ':') {
 
280
                                        tokptr[strlen(tokptr) - 2] = '\0';
 
281
                                        arg_opt = optional_argument;
290
282
                                } else {
291
 
                                        tokptr[strlen(tokptr)-1]='\0';
292
 
                                        arg_opt=required_argument;
 
283
                                        tokptr[strlen(tokptr) - 1] = '\0';
 
284
                                        arg_opt = required_argument;
293
285
                                }
294
286
                                if (strlen(tokptr) == 0)
295
 
                                        parse_error(_("empty long option after "
296
 
                                                      "-l or --long argument"));
 
287
                                        parse_error(_
 
288
                                                    ("empty long option after "
 
289
                                                     "-l or --long argument"));
297
290
                        }
298
 
                        add_longopt(tokptr,arg_opt);
 
291
                        add_longopt(tokptr, arg_opt);
299
292
                }
300
 
                tokptr=strtok(NULL,", \t\n");
 
293
                tokptr = strtok(NULL, ", \t\n");
301
294
        }
302
295
}
303
296
 
304
 
void set_shell(const char *new_shell)
 
297
static void set_shell(const char *new_shell)
305
298
{
306
 
        if (!strcmp(new_shell,"bash"))
307
 
                shell=BASH;
308
 
        else if (!strcmp(new_shell,"tcsh"))
309
 
                shell=TCSH;
310
 
        else if (!strcmp(new_shell,"sh"))
311
 
                shell=BASH;
312
 
        else if (!strcmp(new_shell,"csh"))
313
 
                shell=TCSH;
 
299
        if (!strcmp(new_shell, "bash"))
 
300
                shell = BASH;
 
301
        else if (!strcmp(new_shell, "tcsh"))
 
302
                shell = TCSH;
 
303
        else if (!strcmp(new_shell, "sh"))
 
304
                shell = BASH;
 
305
        else if (!strcmp(new_shell, "csh"))
 
306
                shell = TCSH;
314
307
        else
315
 
                parse_error(_("unknown shell after -s or --shell argument"));
 
308
                parse_error(_
 
309
                            ("unknown shell after -s or --shell argument"));
316
310
}
317
311
 
318
 
void print_help(void)
 
312
static void __attribute__ ((__noreturn__)) print_help(void)
319
313
{
320
 
        fputs(_("Usage: getopt optstring parameters\n"),stderr);
321
 
        fputs(_("       getopt [options] [--] optstring parameters\n"),stderr);
322
 
        fputs(_("       getopt [options] -o|--options optstring [options] [--]\n"),stderr);
323
 
        fputs(_("              parameters\n"),stderr);
324
 
        fputs(_("  -a, --alternative            Allow long options starting with single -\n"),stderr);
325
 
        fputs(_("  -h, --help                   This small usage guide\n"),stderr);
326
 
        fputs(_("  -l, --longoptions=longopts   Long options to be recognized\n"),stderr);
327
 
        fputs(_("  -n, --name=progname          The name under which errors are reported\n"),stderr);
328
 
        fputs(_("  -o, --options=optstring      Short options to be recognized\n"),stderr);
329
 
        fputs(_("  -q, --quiet                  Disable error reporting by getopt(3)\n"),stderr);
330
 
        fputs(_("  -Q, --quiet-output           No normal output\n"),stderr);
331
 
        fputs(_("  -s, --shell=shell            Set shell quoting conventions\n"),stderr);      
332
 
        fputs(_("  -T, --test                   Test for getopt(1) version\n"),stderr);
333
 
        fputs(_("  -u, --unqote                 Do not quote the output\n"),stderr);
334
 
        fputs(_("  -V, --version                Output version information\n"),stderr);
335
 
        exit(2);
 
314
        fputs(_("\nUsage:\n"), stderr);
 
315
 
 
316
        fprintf(stderr, _(
 
317
                " %1$s optstring parameters\n"
 
318
                " %1$s [options] [--] optstring parameters\n"
 
319
                " %1$s [options] -o|--options optstring [options] [--] parameters\n"),
 
320
                program_invocation_short_name);
 
321
 
 
322
        fputs(_("\nOptions:\n"), stderr);
 
323
        fputs(_(" -a, --alternative            Allow long options starting with single -\n"), stderr);
 
324
        fputs(_(" -h, --help                   This small usage guide\n"), stderr);
 
325
        fputs(_(" -l, --longoptions <longopts> Long options to be recognized\n"), stderr);
 
326
        fputs(_(" -n, --name <progname>        The name under which errors are reported\n"), stderr);
 
327
        fputs(_(" -o, --options <optstring>    Short options to be recognized\n"), stderr);
 
328
        fputs(_(" -q, --quiet                  Disable error reporting by getopt(3)\n"), stderr);
 
329
        fputs(_(" -Q, --quiet-output           No normal output\n"), stderr);
 
330
        fputs(_(" -s, --shell <shell>          Set shell quoting conventions\n"), stderr);
 
331
        fputs(_(" -T, --test                   Test for getopt(1) version\n"), stderr);
 
332
        fputs(_(" -u, --unquote                Do not quote the output\n"), stderr);
 
333
        fputs(_(" -V, --version                Output version information\n"), stderr);
 
334
        fputc('\n', stderr);
 
335
 
 
336
        exit(PARAMETER_EXIT_CODE);
336
337
}
337
 
        
338
 
/* Exit codes:
339
 
 *   0) No errors, succesful operation.
340
 
 *   1) getopt(3) returned an error.
341
 
 *   2) A problem with parameter parsing for getopt(1).
342
 
 *   3) Internal error, out of memory
343
 
 *   4) Returned for -T
344
 
 */
345
 
 
346
 
static struct option longopts[]={ {"options",required_argument,NULL,'o'},
347
 
                                  {"longoptions",required_argument,NULL,'l'},
348
 
                                  {"quiet",no_argument,NULL,'q'},
349
 
                                  {"quiet-output",no_argument,NULL,'Q'},
350
 
                                  {"shell",required_argument,NULL,'s'},
351
 
                                  {"test",no_argument,NULL,'T'},
352
 
                                  {"unquoted",no_argument,NULL,'u'},
353
 
                                  {"help",no_argument,NULL,'h'},
354
 
                                  {"alternative",no_argument,NULL,'a'},
355
 
                                  {"name",required_argument,NULL,'n'},
356
 
                                  {"version",no_argument,NULL,'V'},
357
 
                                  {NULL,0,NULL,0}
358
 
                                };
359
 
 
360
 
/* Stop scanning as soon as a non-option argument is found! */
361
 
static const char *shortopts="+ao:l:n:qQs:TuhV";
362
338
 
363
339
int main(int argc, char *argv[])
364
340
{
365
 
        char *optstr=NULL;
366
 
        char *name=NULL;
 
341
        char *optstr = NULL;
 
342
        char *name = NULL;
367
343
        int opt;
368
 
        int compatible=0;
369
 
 
370
 
        setlocale(LC_ALL,"");
 
344
        int compatible = 0;
 
345
 
 
346
        /* Stop scanning as soon as a non-option argument is found! */
 
347
        static const char *shortopts = "+ao:l:n:qQs:TuhV";
 
348
        static const struct option longopts[] = {
 
349
                {"options", required_argument, NULL, 'o'},
 
350
                {"longoptions", required_argument, NULL, 'l'},
 
351
                {"quiet", no_argument, NULL, 'q'},
 
352
                {"quiet-output", no_argument, NULL, 'Q'},
 
353
                {"shell", required_argument, NULL, 's'},
 
354
                {"test", no_argument, NULL, 'T'},
 
355
                {"unquoted", no_argument, NULL, 'u'},
 
356
                {"help", no_argument, NULL, 'h'},
 
357
                {"alternative", no_argument, NULL, 'a'},
 
358
                {"name", required_argument, NULL, 'n'},
 
359
                {"version", no_argument, NULL, 'V'},
 
360
                {NULL, 0, NULL, 0}
 
361
        };
 
362
 
 
363
        setlocale(LC_ALL, "");
371
364
        bindtextdomain(PACKAGE, LOCALEDIR);
372
365
        textdomain(PACKAGE);
373
366
 
374
367
        init_longopt();
375
 
 
376
 
        if (getenv("GETOPT_COMPATIBLE")) 
377
 
                compatible=1;
378
 
 
379
 
        if (argc == 1) 
380
 
        {
 
368
        getopt_long_fp = getopt_long;
 
369
 
 
370
        if (getenv("GETOPT_COMPATIBLE"))
 
371
                compatible = 1;
 
372
 
 
373
        if (argc == 1) {
381
374
                if (compatible) {
382
 
                        /* For some reason, the original getopt gave no error
383
 
                           when there were no arguments. */
 
375
                        /*
 
376
                         * For some reason, the original getopt gave no
 
377
                         * error when there were no arguments.
 
378
                         */
384
379
                        printf(" --\n");
385
 
                        exit(0);
386
 
                }
387
 
                else
 
380
                        return EXIT_SUCCESS;
 
381
                } else
388
382
                        parse_error(_("missing optstring argument"));
389
383
        }
390
 
        
 
384
 
391
385
        if (argv[1][0] != '-' || compatible) {
392
 
                quote=0;
393
 
                optstr=our_malloc(strlen(argv[1])+1);
394
 
                strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
395
 
                argv[1]=argv[0];
396
 
                exit(generate_output(argv+1,argc-1,optstr,long_options));
 
386
                quote = 0;
 
387
                optstr = xmalloc(strlen(argv[1]) + 1);
 
388
                strcpy(optstr, argv[1] + strspn(argv[1], "-+"));
 
389
                argv[1] = argv[0];
 
390
                return generate_output(argv + 1, argc - 1, optstr,
 
391
                                       long_options);
397
392
        }
398
 
        
399
 
        while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF) 
 
393
 
 
394
        while ((opt =
 
395
                getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF)
400
396
                switch (opt) {
401
397
                case 'a':
402
 
                        alternative=1;
 
398
                        getopt_long_fp = getopt_long_only;
403
399
                        break;
404
400
                case 'h':
405
401
                        print_help();
406
 
                        exit(0);
407
402
                case 'o':
408
403
                        free(optstr);
409
 
                        optstr=our_malloc(strlen(optarg)+1);
410
 
                        strcpy(optstr,optarg);
 
404
                        optstr = xmalloc(strlen(optarg) + 1);
 
405
                        strcpy(optstr, optarg);
411
406
                        break;
412
407
                case 'l':
413
408
                        add_long_options(optarg);
414
409
                        break;
415
410
                case 'n':
416
411
                        free(name);
417
 
                        name=our_malloc(strlen(optarg)+1);
418
 
                        strcpy(name,optarg);
 
412
                        name = xmalloc(strlen(optarg) + 1);
 
413
                        strcpy(name, optarg);
419
414
                        break;
420
415
                case 'q':
421
 
                        quiet_errors=1;
 
416
                        quiet_errors = 1;
422
417
                        break;
423
418
                case 'Q':
424
 
                        quiet_output=1;
 
419
                        quiet_output = 1;
425
420
                        break;
426
421
                case 's':
427
422
                        set_shell(optarg);
428
423
                        break;
429
424
                case 'T':
430
 
                        exit(4);
 
425
                        return TEST_EXIT_CODE;
431
426
                case 'u':
432
 
                        quote=0;
 
427
                        quote = 0;
433
428
                        break;
434
429
                case 'V':
435
 
                        printf(_("getopt (enhanced) 1.1.4\n"));
436
 
                        exit(0);
 
430
                        printf(_("%s from %s\n"),
 
431
                               program_invocation_short_name,
 
432
                               PACKAGE_STRING);
 
433
                        return EXIT_SUCCESS;
437
434
                case '?':
438
435
                case ':':
439
436
                        parse_error(NULL);
441
438
                        parse_error(_("internal error, contact the author."));
442
439
                }
443
440
        
444
 
        if (!optstr) 
445
 
        {
 
441
        if (!optstr) {
446
442
                if (optind >= argc)
447
443
                        parse_error(_("missing optstring argument"));
448
444
                else {
449
 
                        optstr=our_malloc(strlen(argv[optind])+1);
450
 
                        strcpy(optstr,argv[optind]);
 
445
                        optstr = xmalloc(strlen(argv[optind]) + 1);
 
446
                        strcpy(optstr, argv[optind]);
451
447
                        optind++;
452
448
                }
453
449
        }
454
450
        if (name)
455
 
                argv[optind-1]=name;
 
451
                argv[optind - 1] = name;
456
452
        else
457
 
                argv[optind-1]=argv[0];
458
 
        exit(generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
 
453
                argv[optind - 1] = argv[0];
 
454
 
 
455
        return generate_output(argv + optind - 1, argc-optind + 1,
 
456
                               optstr, long_options);
459
457
}