getopt: use xalloc.h

The xalloc fix requires exit codes to symbolical refrences to
overwrite default value on error.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2011-06-12 23:31:59 +02:00
parent a5463f78f8
commit d1d03b54d9
1 changed files with 29 additions and 47 deletions

View File

@ -39,6 +39,18 @@
* Fixed a few type's in the manpage
*/
/* Exit codes:
* 0) No errors, succesful operation.
* 1) getopt(3) returned an error.
* 2) A problem with parameter parsing for getopt(1).
* 3) Internal error, out of memory
* 4) Returned for -T
*/
#define GETOPT_EXIT_CODE 1
#define PARAMETER_EXIT_CODE 2
#define XALLOC_EXIT_CODE 3
#define TEST_EXIT_CODE 4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -47,6 +59,7 @@
#include <getopt.h>
#include "nls.h"
#include "xalloc.h"
/* NON_OPT is the code that is returned when a non-option is found in '+'
mode */
@ -66,8 +79,6 @@ static int quote=1; /* 1 is do quote. */
static int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
/* Function prototypes */
static void *our_malloc(size_t size);
static void *our_realloc(void *ptr, size_t size);
static const char *normalize(const char *arg);
static int generate_output(char * argv[],int argc,const char *optstr,
const struct option *longopts);
@ -78,26 +89,6 @@ static void add_longopt(const char *name,int has_arg);
static void print_help(void);
static void set_shell(const char *new_shell);
static void *our_malloc(size_t size)
{
void *ret=malloc(size);
if (! ret) {
fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
exit(3);
}
return(ret);
}
static void *our_realloc(void *ptr, size_t size)
{
void *ret=realloc(ptr,size);
if (! ret && size) {
fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
exit(3);
}
return(ret);
}
/*
* This function 'normalizes' a single argument: it puts single quotes around
* it and escapes other special characters. If quote is false, it just
@ -116,7 +107,7 @@ static const char *normalize(const char *arg)
free(BUFFER);
if (!quote) { /* Just copy arg */
BUFFER=our_malloc(strlen(arg)+1);
BUFFER=xmalloc(strlen(arg)+1);
strcpy(BUFFER,arg);
return BUFFER;
@ -126,7 +117,7 @@ static const char *normalize(const char *arg)
For a quote we need a closing quote, a backslash, a quote and an
opening quote! We need also the global opening and closing quote,
and one extra character for '\0'. */
BUFFER=our_malloc(strlen(arg)*4+3);
BUFFER=xmalloc(strlen(arg)*4+3);
bufptr=BUFFER;
*bufptr++='\'';
@ -188,7 +179,7 @@ static int generate_output(char * argv[],int argc,const char *optstr,
getopt_long(argc,argv,optstr,longopts,&longindex)))
!= EOF)
if (opt == '?' || opt == ':' )
exit_code = 1;
exit_code = GETOPT_EXIT_CODE;
else if (!quiet_output)
{
if (opt == LONG_OPT) {
@ -226,7 +217,7 @@ static void parse_error(const char *message)
if (message)
fprintf(stderr,"getopt: %s\n",message);
fputs(_("Try `getopt --help' for more information.\n"),stderr);
exit(2);
exit(PARAMETER_EXIT_CODE);
}
static struct option *long_options=NULL;
@ -248,7 +239,7 @@ static void add_longopt(const char *name,int has_arg)
if (long_options_nr == long_options_length) {
long_options_length += LONG_OPTIONS_INCR;
long_options=our_realloc(long_options,
long_options=xrealloc(long_options,
sizeof(struct option) *
long_options_length);
}
@ -262,7 +253,7 @@ static void add_longopt(const char *name,int has_arg)
long_options[long_options_nr-1].has_arg=has_arg;
long_options[long_options_nr-1].flag=NULL;
long_options[long_options_nr-1].val=LONG_OPT;
tmp = our_malloc(strlen(name)+1);
tmp = xmalloc(strlen(name)+1);
strcpy(tmp,name);
long_options[long_options_nr-1].name=tmp;
}
@ -331,17 +322,9 @@ static void print_help(void)
fputs(_(" -T, --test Test for getopt(1) version\n"),stderr);
fputs(_(" -u, --unquote Do not quote the output\n"),stderr);
fputs(_(" -V, --version Output version information\n"),stderr);
exit(2);
exit(PARAMETER_EXIT_CODE);
}
/* Exit codes:
* 0) No errors, succesful operation.
* 1) getopt(3) returned an error.
* 2) A problem with parameter parsing for getopt(1).
* 3) Internal error, out of memory
* 4) Returned for -T
*/
static struct option longopts[]={ {"options",required_argument,NULL,'o'},
{"longoptions",required_argument,NULL,'l'},
{"quiet",no_argument,NULL,'q'},
@ -381,7 +364,7 @@ int main(int argc, char *argv[])
/* For some reason, the original getopt gave no error
when there were no arguments. */
printf(" --\n");
exit(0);
return EXIT_SUCCESS;
}
else
parse_error(_("missing optstring argument"));
@ -389,10 +372,10 @@ int main(int argc, char *argv[])
if (argv[1][0] != '-' || compatible) {
quote=0;
optstr=our_malloc(strlen(argv[1])+1);
optstr=xmalloc(strlen(argv[1])+1);
strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
argv[1]=argv[0];
exit(generate_output(argv+1,argc-1,optstr,long_options));
return generate_output(argv+1,argc-1,optstr,long_options);
}
while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
@ -402,10 +385,9 @@ int main(int argc, char *argv[])
break;
case 'h':
print_help();
exit(0);
case 'o':
free(optstr);
optstr=our_malloc(strlen(optarg)+1);
optstr=xmalloc(strlen(optarg)+1);
strcpy(optstr,optarg);
break;
case 'l':
@ -413,7 +395,7 @@ int main(int argc, char *argv[])
break;
case 'n':
free(name);
name=our_malloc(strlen(optarg)+1);
name=xmalloc(strlen(optarg)+1);
strcpy(name,optarg);
break;
case 'q':
@ -426,12 +408,12 @@ int main(int argc, char *argv[])
set_shell(optarg);
break;
case 'T':
exit(4);
return TEST_EXIT_CODE;
case 'u':
quote=0;
break;
case 'V':
printf(_("getopt (enhanced) 1.1.4\n"));
printf(_("getopt (enhanced) 1.1.4\n"));
exit(0);
case '?':
case ':':
@ -445,7 +427,7 @@ int main(int argc, char *argv[])
if (optind >= argc)
parse_error(_("missing optstring argument"));
else {
optstr=our_malloc(strlen(argv[optind])+1);
optstr=xmalloc(strlen(argv[optind])+1);
strcpy(optstr,argv[optind]);
optind++;
}
@ -454,5 +436,5 @@ int main(int argc, char *argv[])
argv[optind-1]=name;
else
argv[optind-1]=argv[0];
exit(generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
return generate_output(argv+optind-1,argc-optind+1,optstr,long_options);
}