Mercurial > repos > clustalomega > clustalomega
diff clustalomega/clustal-omega-0.2.0/src/squid/getopt.c @ 0:ff1768533a07
Migrated tool version 0.2 from old tool shed archive to new tool shed repository
author | clustalomega |
---|---|
date | Tue, 07 Jun 2011 17:04:25 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clustalomega/clustal-omega-0.2.0/src/squid/getopt.c Tue Jun 07 17:04:25 2011 -0400 @@ -0,0 +1,250 @@ +/***************************************************************** + * SQUID - a library of functions for biological sequence analysis + * Copyright (C) 1992-2002 Washington University School of Medicine + * + * This source code is freely distributed under the terms of the + * GNU General Public License. See the files COPYRIGHT and LICENSE + * for details. + *****************************************************************/ + +/* RCS $Id: getopt.c 217 2011-03-19 10:27:10Z andreas $ (Original squid RCS Id: getopt.c,v 1.7 2001/02/21 21:09:10 eddy Exp) + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "squid.h" + +/* Function: Getopt() + * + * Purpose: Portable command line option parsing with abbreviated + * option switches. Replaces UNIX getopt(). Using UNIX getopt() + * hinders portability to non-UNIX platforms, and getopt() + * is also limited to single letter options. + * + * Getopt() implements a superset of UNIX getopt(). + * All of getopt()'s single-character switch behavior + * is emulated, and "--" by itself terminates the options. + * Additionally, Getopt() provides extended switches + * like "--youroptionhere", and Getopt() type checks + * arguments. + * + * Extended options must start with "--", as in "--option1". + * Normal options must start with "-", as in "-o". + * Normal options may be concatenated, as in "-a -b" == "-ab". + * + * See bottom of this .c file after #fdef GETOPT_TESTDRIVER + * for an example of calling Getopt(). + * + * Args: argc - from main(). number of elems in argv. + * argv - from main(). argv[0] is the name of the command. + * opt - array of opt_s structures, defining option switches + * nopts - number of switches in opt + * usage - a (possibly long) string to print if usage error. + * ret_optind - RETURN: the index in argv[] of the next + * valid command-line token. + * ret_optname- RETURN: ptr to the name of option switch + * seen, or NULL if no option was seen. + * ret_optarg - RETURN: ptr to the optional argument, if any; + * NULL if option takes no argument. + * + * Return: 1 if a valid option was parsed. + * 0 if no option was found, and command-line parsing is complete. + * Die()'s here if an error is detected. + */ +int +Getopt(int argc, char **argv, struct opt_s *opt, int nopts, char *usage, + int *ret_optind, char **ret_optname, char **ret_optarg) +{ + int i; + int arglen; + int nmatch; + static int optind = 1; /* init to 1 on first call */ + static char *optptr = NULL; /* ptr to next valid switch */ + int opti = 0; /* init only to silence gcc uninit warnings */ + + /* Check to see if we've run out of options. + * A '-' by itself is an argument (e.g. "read from stdin") + * not an option. + */ + if (optind >= argc || argv[optind][0] != '-' || strcmp(argv[optind], "-") == 0) + { + *ret_optind = optind; + *ret_optarg = NULL; + *ret_optname = NULL; + return 0; + } + + /* Check to see if we're being told that this is the end + * of the options with the special "--" flag. + */ + if (strcmp(argv[optind], "--") == 0) + { + optind++; + *ret_optind = optind; + *ret_optname = NULL; + *ret_optarg = NULL; + return 0; + } + + /* We have a real option. Find which one it is. + * We handle single letter switches "-o" separately + * from full switches "--option", based on the "-" vs. "--" + * prefix -- single letter switches can be concatenated + * as long as they don't have arguments. + */ + /* full option */ + if (optptr == NULL && strncmp(argv[optind], "--", 2) == 0) + { + /* Use optptr to parse argument in options of form "--foo=666" + */ + if ((optptr = strchr(argv[optind], '=')) != NULL) + { *optptr = '\0'; optptr++; } + + arglen = strlen(argv[optind]); + nmatch = 0; + for (i = 0; i < nopts; i++) + if (opt[i].single == FALSE && + strncmp(opt[i].name, argv[optind], arglen) == 0) + { + nmatch++; + opti = i; + if (arglen == strlen(opt[i].name)) break; /* exact match, stop now */ + } + if (nmatch > 1 && arglen != strlen(opt[i].name)) + Die("Option \"%s\" is ambiguous; please be more specific.\n%s", + argv[optind], usage); + if (nmatch == 0) + Die("No such option \"%s\".\n%s", argv[optind], usage); + + *ret_optname = opt[opti].name; + + /* Set the argument, if there is one + */ + if (opt[opti].argtype != sqdARG_NONE) + { + if (optptr != NULL) + { /* --foo=666 style */ + *ret_optarg = optptr; + optptr = NULL; + optind++; + } + else if (optind+1 >= argc) + Die("Option %s requires an argument\n%s", opt[opti].name, usage); + else /* "--foo 666" style */ + { + *ret_optarg = argv[optind+1]; + optind+=2; + } + } + else /* sqdARG_NONE */ + { + if (optptr != NULL) + Die("Option %s does not take an argument\n%s", opt[opti].name, usage); + *ret_optarg = NULL; + optind++; + } + } + else /* else, a single letter option "-o" */ + { + /* find the option */ + if (optptr == NULL) + optptr = argv[optind]+1; + for (opti = -1, i = 0; i < nopts; i++) + if (opt[i].single == TRUE && *optptr == opt[i].name[1]) + { opti = i; break; } + if (opti == -1) + Die("No such option \"%c\".\n%s", *optptr, usage); + *ret_optname = opt[opti].name; + + /* set the argument, if there is one */ + if (opt[opti].argtype != sqdARG_NONE) + { + if (*(optptr+1) != '\0') /* attached argument */ + { + *ret_optarg = optptr+1; + optind++; + } + else if (optind+1 < argc) /* unattached argument */ + { + *ret_optarg = argv[optind+1]; + optind+=2; + } + else Die("Option %s requires an argument\n%s", opt[opti].name, usage); + + optptr = NULL; /* can't concatenate after an argument */ + } + else /* sqdARG_NONE */ + { + *ret_optarg = NULL; + if (*(optptr+1) != '\0') /* concatenation */ + optptr++; + else + { + optind++; /* move to next field */ + optptr = NULL; + } + } + + } + + /* Type check the argument, if there is one + */ + if (opt[opti].argtype != sqdARG_NONE) + { + if (opt[opti].argtype == sqdARG_INT && ! IsInt(*ret_optarg)) + Die("Option %s requires an integer argument\n%s", + opt[opti].name, usage); + else if (opt[opti].argtype == sqdARG_FLOAT && ! IsReal(*ret_optarg)) + Die("Option %s requires a numerical argument\n%s", + opt[opti].name, usage); + else if (opt[opti].argtype == sqdARG_CHAR && strlen(*ret_optarg) != 1) + Die("Option %s requires a single-character argument\n%s", + opt[opti].name, usage); + /* sqdARG_STRING is always ok, no type check necessary */ + } + + *ret_optind = optind; + return 1; +} + + + +#ifdef GETOPT_TESTDRIVER +/* cc -DGETOPT_TESTDRIVER -L ~/lib/squid.linux/ getopt.c -lsquid + */ +struct opt_s OPTIONS[] = { + { "--test1", FALSE, sqdARG_INT }, + { "--test2", FALSE, sqdARG_FLOAT }, + { "--test3", FALSE, sqdARG_STRING }, + { "--test4", FALSE, sqdARG_CHAR }, + { "-a", TRUE, sqdARG_NONE }, + { "-b", TRUE, sqdARG_INT }, +}; +#define NOPTIONS (sizeof(OPTIONS) / sizeof(struct opt_s)) + +int +main(int argc, char **argv) +{ + int optind; + char *optarg; + char *optname; + + while (Getopt(argc, argv, OPTIONS, NOPTIONS, "Usage/help here", + &optind, &optname, &optarg)) + { + printf("Option: index: %d name: %s argument: %s\n", + optind, optname, optarg); + } + while (optind < argc) + { + printf("Argument: index: %d name: %s\n", optind, argv[optind]); + optind++; + } + + +} + + +#endif /*GETOPT_TESTDRIVER*/