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 * 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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -47,6 +59,7 @@
#include <getopt.h> #include <getopt.h>
#include "nls.h" #include "nls.h"
#include "xalloc.h"
/* NON_OPT is the code that is returned when a non-option is found in '+' /* NON_OPT is the code that is returned when a non-option is found in '+'
mode */ 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 */ static int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
/* Function prototypes */ /* 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 const char *normalize(const char *arg);
static int generate_output(char * argv[],int argc,const char *optstr, static int generate_output(char * argv[],int argc,const char *optstr,
const struct option *longopts); 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 print_help(void);
static void set_shell(const char *new_shell); 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 * This function 'normalizes' a single argument: it puts single quotes around
* it and escapes other special characters. If quote is false, it just * 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); free(BUFFER);
if (!quote) { /* Just copy arg */ if (!quote) { /* Just copy arg */
BUFFER=our_malloc(strlen(arg)+1); BUFFER=xmalloc(strlen(arg)+1);
strcpy(BUFFER,arg); strcpy(BUFFER,arg);
return BUFFER; 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 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, opening quote! We need also the global opening and closing quote,
and one extra character for '\0'. */ and one extra character for '\0'. */
BUFFER=our_malloc(strlen(arg)*4+3); BUFFER=xmalloc(strlen(arg)*4+3);
bufptr=BUFFER; bufptr=BUFFER;
*bufptr++='\''; *bufptr++='\'';
@ -188,7 +179,7 @@ static int generate_output(char * argv[],int argc,const char *optstr,
getopt_long(argc,argv,optstr,longopts,&longindex))) getopt_long(argc,argv,optstr,longopts,&longindex)))
!= EOF) != EOF)
if (opt == '?' || opt == ':' ) if (opt == '?' || opt == ':' )
exit_code = 1; exit_code = GETOPT_EXIT_CODE;
else if (!quiet_output) else if (!quiet_output)
{ {
if (opt == LONG_OPT) { if (opt == LONG_OPT) {
@ -226,7 +217,7 @@ static void parse_error(const char *message)
if (message) if (message)
fprintf(stderr,"getopt: %s\n",message); fprintf(stderr,"getopt: %s\n",message);
fputs(_("Try `getopt --help' for more information.\n"),stderr); fputs(_("Try `getopt --help' for more information.\n"),stderr);
exit(2); exit(PARAMETER_EXIT_CODE);
} }
static struct option *long_options=NULL; 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) { if (long_options_nr == long_options_length) {
long_options_length += LONG_OPTIONS_INCR; long_options_length += LONG_OPTIONS_INCR;
long_options=our_realloc(long_options, long_options=xrealloc(long_options,
sizeof(struct option) * sizeof(struct option) *
long_options_length); 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].has_arg=has_arg;
long_options[long_options_nr-1].flag=NULL; long_options[long_options_nr-1].flag=NULL;
long_options[long_options_nr-1].val=LONG_OPT; long_options[long_options_nr-1].val=LONG_OPT;
tmp = our_malloc(strlen(name)+1); tmp = xmalloc(strlen(name)+1);
strcpy(tmp,name); strcpy(tmp,name);
long_options[long_options_nr-1].name=tmp; 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(_(" -T, --test Test for getopt(1) version\n"),stderr);
fputs(_(" -u, --unquote Do not quote the output\n"),stderr); fputs(_(" -u, --unquote Do not quote the output\n"),stderr);
fputs(_(" -V, --version Output version information\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'}, static struct option longopts[]={ {"options",required_argument,NULL,'o'},
{"longoptions",required_argument,NULL,'l'}, {"longoptions",required_argument,NULL,'l'},
{"quiet",no_argument,NULL,'q'}, {"quiet",no_argument,NULL,'q'},
@ -381,7 +364,7 @@ int main(int argc, char *argv[])
/* For some reason, the original getopt gave no error /* For some reason, the original getopt gave no error
when there were no arguments. */ when there were no arguments. */
printf(" --\n"); printf(" --\n");
exit(0); return EXIT_SUCCESS;
} }
else else
parse_error(_("missing optstring argument")); parse_error(_("missing optstring argument"));
@ -389,10 +372,10 @@ int main(int argc, char *argv[])
if (argv[1][0] != '-' || compatible) { if (argv[1][0] != '-' || compatible) {
quote=0; quote=0;
optstr=our_malloc(strlen(argv[1])+1); optstr=xmalloc(strlen(argv[1])+1);
strcpy(optstr,argv[1]+strspn(argv[1],"-+")); strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
argv[1]=argv[0]; 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) while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
@ -402,10 +385,9 @@ int main(int argc, char *argv[])
break; break;
case 'h': case 'h':
print_help(); print_help();
exit(0);
case 'o': case 'o':
free(optstr); free(optstr);
optstr=our_malloc(strlen(optarg)+1); optstr=xmalloc(strlen(optarg)+1);
strcpy(optstr,optarg); strcpy(optstr,optarg);
break; break;
case 'l': case 'l':
@ -413,7 +395,7 @@ int main(int argc, char *argv[])
break; break;
case 'n': case 'n':
free(name); free(name);
name=our_malloc(strlen(optarg)+1); name=xmalloc(strlen(optarg)+1);
strcpy(name,optarg); strcpy(name,optarg);
break; break;
case 'q': case 'q':
@ -426,12 +408,12 @@ int main(int argc, char *argv[])
set_shell(optarg); set_shell(optarg);
break; break;
case 'T': case 'T':
exit(4); return TEST_EXIT_CODE;
case 'u': case 'u':
quote=0; quote=0;
break; break;
case 'V': case 'V':
printf(_("getopt (enhanced) 1.1.4\n")); printf(_("getopt (enhanced) 1.1.4\n"));
exit(0); exit(0);
case '?': case '?':
case ':': case ':':
@ -445,7 +427,7 @@ int main(int argc, char *argv[])
if (optind >= argc) if (optind >= argc)
parse_error(_("missing optstring argument")); parse_error(_("missing optstring argument"));
else { else {
optstr=our_malloc(strlen(argv[optind])+1); optstr=xmalloc(strlen(argv[optind])+1);
strcpy(optstr,argv[optind]); strcpy(optstr,argv[optind]);
optind++; optind++;
} }
@ -454,5 +436,5 @@ int main(int argc, char *argv[])
argv[optind-1]=name; argv[optind-1]=name;
else else
argv[optind-1]=argv[0]; 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);
} }