/[public]/getopt/trunk/getopt.c
ViewVC logotype

Diff of /getopt/trunk/getopt.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 317 Revision 319
37 * <misiek@pld.org.pl>) 37 * <misiek@pld.org.pl>)
38 * Version 1.1.4: Mon Nov 7 2005 38 * Version 1.1.4: Mon Nov 7 2005
39 * Fixed a few type's in the manpage 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
54
42#include <stdio.h> 55#include <stdio.h>
43#include <stdlib.h> 56#include <stdlib.h>
44#include <string.h> 57#include <string.h>
45#include <unistd.h> 58#include <unistd.h>
46#include <ctype.h> 59#include <ctype.h>
66/* Some global variables that tells us how to parse. */ 79/* Some global variables that tells us how to parse. */
67shell_t shell=BASH; /* The shell we generate output for. */ 80shell_t shell=BASH; /* The shell we generate output for. */
68int quiet_errors=0; /* 0 is not quiet. */ 81int quiet_errors=0; /* 0 is not quiet. */
69int quiet_output=0; /* 0 is not quiet. */ 82int quiet_output=0; /* 0 is not quiet. */
70int quote=1; /* 1 is do quote. */ 83int quote=1; /* 1 is do quote. */
71int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */ 84
85int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
86 const struct option * longopts, int *longindex);
72 87
73/* Function prototypes */ 88/* Function prototypes */
74void *our_malloc(size_t size); 89void *our_malloc(size_t size);
75void *our_realloc(void *ptr, size_t size); 90void *our_realloc(void *ptr, size_t size);
76const char *normalize(const char *arg); 91const char *normalize(const char *arg);
87void *our_malloc(size_t size) 102void *our_malloc(size_t size)
88{ 103{
89 void *ret=malloc(size); 104 void *ret=malloc(size);
90 if (! ret) { 105 if (! ret) {
91 fprintf(stderr,_("%s: Out of memory!\n"),"getopt"); 106 fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
92 exit(3); 107 exit(XALLOC_EXIT_CODE);
93 } 108 }
94 return(ret); 109 return(ret);
95} 110}
96 111
97void *our_realloc(void *ptr, size_t size) 112void *our_realloc(void *ptr, size_t size)
98{ 113{
99 void *ret=realloc(ptr,size); 114 void *ret=realloc(ptr,size);
100 if (! ret && size) { 115 if (! ret && size) {
101 fprintf(stderr,_("%s: Out of memory!\n"),"getopt"); 116 fprintf(stderr,_("%s: Out of memory!\n"),"getopt");
102 exit(3); 117 exit(XALLOC_EXIT_CODE);
103 } 118 }
104 return(ret); 119 return(ret);
105} 120}
106 121
107/* 122/*
182 * Other settings are found in global variables. 197 * Other settings are found in global variables.
183 */ 198 */
184int generate_output(char * argv[],int argc,const char *optstr, 199int generate_output(char * argv[],int argc,const char *optstr,
185 const struct option *longopts) 200 const struct option *longopts)
186{ 201{
187 int exit_code = 0; /* Assume everything will be OK */ 202 int exit_code = EXIT_SUCCESS; /* Assume everything will be OK */
188 int opt; 203 int opt;
189 int longindex; 204 int longindex;
190 const char *charptr; 205 const char *charptr;
191 206
192 if (quiet_errors) 207 if (quiet_errors)
193 /* No error reporting from getopt(3) */ 208 /* No error reporting from getopt(3) */
194 opterr=0; 209 opterr=0;
195 /* Reset getopt(3) */ 210 /* Reset getopt(3) */
196 optind=0; 211 optind=0;
197 212
198 while ((opt = (alternative? 213 while ((opt =
199 getopt_long_only(argc,argv,optstr,longopts,&longindex):
200 getopt_long(argc,argv,optstr,longopts,&longindex))) 214 (getopt_long_fp(argc, argv, optstr, longopts, &longindex)))
201 != EOF) 215 != EOF)
202 if (opt == '?' || opt == ':' ) 216 if (opt == '?' || opt == ':' )
203 exit_code = 1; 217 exit_code = GETOPT_EXIT_CODE;
204 else if (!quiet_output) 218 else if (!quiet_output)
205 { 219 {
206 if (opt == LONG_OPT) { 220 if (opt == LONG_OPT) {
207 printf(" --%s",longopts[longindex].name); 221 printf(" --%s",longopts[longindex].name);
208 if (longopts[longindex].has_arg) 222 if (longopts[longindex].has_arg)
235void parse_error(const char *message) 249void parse_error(const char *message)
236{ 250{
237 if (message) 251 if (message)
238 fprintf(stderr,"getopt: %s\n",message); 252 fprintf(stderr,"getopt: %s\n",message);
239 fputs(_("Try `getopt --help' for more information.\n"),stderr); 253 fputs(_("Try `getopt --help' for more information.\n"),stderr);
240 exit(2); 254 exit(PARAMETER_EXIT_CODE);
241} 255}
242 256
243static struct option *long_options=NULL; 257static struct option *long_options=NULL;
244static int long_options_length=0; /* Length of array */ 258static int long_options_length=0; /* Length of array */
245static int long_options_nr=0; /* Nr of used elements in array */ 259static int long_options_nr=0; /* Nr of used elements in array */
341 fputs(_(" -Q, --quiet-output No normal output\n"),stderr); 355 fputs(_(" -Q, --quiet-output No normal output\n"),stderr);
342 fputs(_(" -s, --shell=shell Set shell quoting conventions\n"),stderr); 356 fputs(_(" -s, --shell=shell Set shell quoting conventions\n"),stderr);
343 fputs(_(" -T, --test Test for getopt(1) version\n"),stderr); 357 fputs(_(" -T, --test Test for getopt(1) version\n"),stderr);
344 fputs(_(" -u, --unqote Do not quote the output\n"),stderr); 358 fputs(_(" -u, --unqote Do not quote the output\n"),stderr);
345 fputs(_(" -V, --version Output version information\n"),stderr); 359 fputs(_(" -V, --version Output version information\n"),stderr);
346 exit(2); 360 exit(PARAMETER_EXIT_CODE);
347} 361}
348 362
349/* Exit codes:
350 * 0) No errors, succesful operation.
351 * 1) getopt(3) returned an error.
352 * 2) A problem with parameter parsing for getopt(1).
353 * 3) Internal error, out of memory
354 * 4) Returned for -T
355 */
356
357static struct option longopts[]={ {"options",required_argument,NULL,'o'}, 363static struct option longopts[]={ {"options",required_argument,NULL,'o'},
358 {"longoptions",required_argument,NULL,'l'}, 364 {"longoptions",required_argument,NULL,'l'},
359 {"quiet",no_argument,NULL,'q'}, 365 {"quiet",no_argument,NULL,'q'},
360 {"quiet-output",no_argument,NULL,'Q'}, 366 {"quiet-output",no_argument,NULL,'Q'},
361 {"shell",required_argument,NULL,'s'}, 367 {"shell",required_argument,NULL,'s'},
384 bindtextdomain(PACKAGE, LOCALEDIR); 390 bindtextdomain(PACKAGE, LOCALEDIR);
385 textdomain(PACKAGE); 391 textdomain(PACKAGE);
386#endif 392#endif
387 393
388 init_longopt(); 394 init_longopt();
395 getopt_long_fp = getopt_long;
389 396
390 if (getenv("GETOPT_COMPATIBLE")) 397 if (getenv("GETOPT_COMPATIBLE"))
391 compatible=1; 398 compatible=1;
392 399
393 if (argc == 1) 400 if (argc == 1)
396 /* 403 /*
397 * For some reason, the original getopt gave no error 404 * For some reason, the original getopt gave no error
398 * when there were no arguments. 405 * when there were no arguments.
399 */ 406 */
400 printf(" --\n"); 407 printf(" --\n");
401 exit(0); 408 return EXIT_SUCCESS;
402 } 409 }
403 else 410 else
404 parse_error(_("missing optstring argument")); 411 parse_error(_("missing optstring argument"));
405 } 412 }
413
406 414
407 if (argv[1][0] != '-' || compatible) { 415 if (argv[1][0] != '-' || compatible) {
408 quote=0; 416 quote=0;
409 optstr=our_malloc(strlen(argv[1])+1); 417 optstr=our_malloc(strlen(argv[1])+1);
410 strcpy(optstr,argv[1]+strspn(argv[1],"-+")); 418 strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
411 argv[1]=argv[0]; 419 argv[1]=argv[0];
412 exit(generate_output(argv+1,argc-1,optstr,long_options)); 420 return generate_output(argv+1,argc-1,optstr,long_options);
413 } 421 }
414 422
415 while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF) 423 while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
416 switch (opt) { 424 switch (opt) {
417 case 'a': 425 case 'a':
418 alternative=1; 426 getopt_long_fp = getopt_long_only;
419 break; 427 break;
420 case 'h': 428 case 'h':
421 print_help(); 429 print_help();
422 exit(0);
423 case 'o': 430 case 'o':
424 if (optstr) 431 if (optstr)
425 free(optstr); 432 free(optstr);
426 optstr=our_malloc(strlen(optarg)+1); 433 optstr=our_malloc(strlen(optarg)+1);
427 strcpy(optstr,optarg); 434 strcpy(optstr,optarg);
443 break; 450 break;
444 case 's': 451 case 's':
445 set_shell(optarg); 452 set_shell(optarg);
446 break; 453 break;
447 case 'T': 454 case 'T':
448 exit(4); 455 return TEST_EXIT_CODE;
449 case 'u': 456 case 'u':
450 quote=0; 457 quote=0;
451 break; 458 break;
452 case 'V': 459 case 'V':
453 printf(_("getopt (enhanced) 1.1.4\n")); 460 printf(_("getopt (enhanced) 1.1.4\n"));
454 exit(0); 461 return EXIT_SUCCESS;
455 case '?': 462 case '?':
456 case ':': 463 case ':':
457 parse_error(NULL); 464 parse_error(NULL);
458 default: 465 default:
459 parse_error(_("internal error, contact the author.")); 466 parse_error(_("internal error, contact the author."));
471 } 478 }
472 if (name) 479 if (name)
473 argv[optind-1]=name; 480 argv[optind-1]=name;
474 else 481 else
475 argv[optind-1]=argv[0]; 482 argv[optind-1]=argv[0];
476 exit(generate_output(argv+optind-1,argc-optind+1,optstr,long_options)); 483 return generate_output(argv+optind-1,argc-optind+1,optstr,long_options);
477} 484}

Legend:
Removed from v.317  
changed lines
  Added in v.319

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26