Show misc_opt.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* libmisc: utilities for parsing options
*
* $Id: misc_opt.c,v 1.14 2005/06/20 00:06:16 girod Exp $
*/
char misc_opt_cvsid[] = "$Id: misc_opt.c,v 1.14 2005/06/20 00:06:16 girod Exp $";
#include <misc.h>
/*
* parse and remove the specified option, returning the argument or
* NULL if not found. if no argument is present, returns ""
*
* The last argument is 'switch_only', in which case this function
* assumes it is looking for a single switch (eg., -t), NOT an option
* followed by an argument (e.g., -t blah).
*/
char *
misc_parse_out_option_aux(int *argc, char **argv, char *option_str,
char option_char, int switch_only)
{
char *retval = NULL;
int prune;
int i;
char buf[128];
char *maybe_optarg;
int optarg_is_equals;
/* parse commandline */
for (i=0; i<(*argc); i++)
if (argv[i]) {
/* assume that optarg might be the next argument */
optarg_is_equals = 0;
maybe_optarg = NULL;
if (i < ((*argc) - 1)) {
if (argv[i+1] && ( (argv[i+1][0] != '-') || ((argv[i+1][0] == '-') && (isdigit(argv[i+1][1])) )) )
maybe_optarg = argv[i+1];
}
/* test longopt */
if (option_str && (strncmp(argv[i], "--", 2) == 0)) {
char *equals;
/* copy, strip past equals, set optarg */
strncpy(buf, argv[i]+2, sizeof(buf));
equals = strpbrk(buf, "=");
if (equals) {
*equals = 0;
maybe_optarg = argv[i]+2+(equals-buf)+1;
optarg_is_equals = 1;
}
if (strcmp(buf, option_str) == 0) {
/* got longopt */
goto got_opt;
}
}
/* test short opt */
else {
if ((argv[i][0] == '-') &&
(argv[i][1] == option_char)) {
/* got short opt */
goto got_opt;
}
}
}
/* no option parsed... */
goto done;
got_opt:
/* if no argument.. */
prune = 1;
retval = "";
/* arg present? */
if (!switch_only && (maybe_optarg != NULL)) {
if (!optarg_is_equals) prune++;
retval = maybe_optarg;
}
/* remove the options from argv */
for (i=i+prune; i<*argc; i++) {
argv[i-prune] = argv[i];
argv[i] = NULL;
}
*argc -= prune;
done:
return retval;
}
/*
* parse out an option followed by an argument, e.g. "-t blah".
*
* Returns NULL if the option is not found.
* Returns "" if the option is found, but is not followed by an argument.
* Returns the argument if the option and its argument are present.
*/
char *
misc_parse_out_option(int *argc, char **argv, char *option_str,
char option_char)
{
return misc_parse_out_option_aux(argc, argv, option_str, option_char, 0);
}
/*
* Parse out a command-line switch, e.g. "-t".
*
* Returns 1 if the switch is present, 0 otherwise.
*/
int
misc_parse_out_switch(int *argc, char **argv, char *option_str,
char option_char)
{
return (misc_parse_out_option_aux(argc, argv, option_str, option_char, 1) != NULL);
}
int misc_parse_option_as_int(int *argc, char **argv,
char *option_str, char option_char, int *value)
{
char *str_value = misc_parse_out_option(argc, argv, option_str, option_char);
if (str_value) {
if (strncasecmp(str_value, "0x", 2) == 0) {
if (1 == sscanf(str_value+2, "%x", value))
return 0;
}
else if (1 == sscanf(str_value, "%d", value))
return 0;
elog(LOG_WARNING, "Parsed invalid option for '%s'[%c]: %s",
option_str, option_char, str_value);
}
return -1;
}
int misc_parse_option_as_uint(int *argc, char **argv,
char *option_str, char option_char, uint *value)
{
char *str_value = misc_parse_out_option(argc, argv, option_str, option_char);
if (str_value) {
if (strncasecmp(str_value, "0x", 2) == 0) {
if (1 == sscanf(str_value+2, "%x", value))
return 0;
}
else if (1 == sscanf(str_value, "%u", value))
return 0;
elog(LOG_WARNING, "Parsed invalid option for '%s'[%c]: %s",
option_str, option_char, str_value);
}
return -1;
}
int misc_parse_option_as_uint8(int *argc, char **argv,
char *option_str, char option_char, uint8_t *value)
{
char *str_value = misc_parse_out_option(argc, argv, option_str, option_char);
if (str_value) {
uint tmp;
if (strncasecmp(str_value, "0x", 2) == 0) {
if (1 == sscanf(str_value+2, "%x", &tmp))
goto check_value;
}
else if (1 == sscanf(str_value, "%u", &tmp))
goto check_value;
elog(LOG_WARNING, "Parsed invalid option for '%s'[%c]: %s",
option_str, option_char, str_value);
return -1;
check_value:
if (tmp > 255) {
elog(LOG_WARNING, "Parsed invalid byte option for '%s'[%c]: %s",
option_str, option_char, str_value);
return -1;
}
*value = tmp;
return 0;
}
return -1;
}
int misc_parse_option_as_uint16(int *argc, char **argv,
char *option_str, char option_char, uint16_t *value)
{
char *str_value = misc_parse_out_option(argc, argv, option_str, option_char);
if (str_value) {
uint tmp;
if (strncasecmp(str_value, "0x", 2) == 0) {
if (1 == sscanf(str_value+2, "%x", &tmp))
goto check_value;
}
else if (1 == sscanf(str_value, "%u", &tmp))
goto check_value;
elog(LOG_WARNING, "Parsed invalid option for '%s'[%c]: %s",
option_str, option_char, str_value);
return -1;
check_value:
if (tmp > 65535) {
elog(LOG_WARNING, "Parsed invalid uint16 option for '%s'[%c]: %s",
option_str, option_char, str_value);
return -1;
}
*value = tmp;
return 0;
}
return -1;
}
int misc_parse_option_as_float(int *argc, char **argv,
char *option_str, char option_char, float *value)
{
char *str_value = misc_parse_out_option(argc, argv, option_str, option_char);
if (str_value) {
if (1 == sscanf(str_value, "%f", value))
return 0;
elog(LOG_WARNING, "Parsed invalid option for '%s'[%c]: %s",
option_str, option_char, str_value);
}
return -1;
}
int misc_args_remain(int *argc, char **argv)
{
if (*argc > 1) {
int i;
for (i=1; i<*argc; i++) {
if (strcmp(argv[i], "--help") == 0) return 1;
if (strcmp(argv[i], "-h") == 0) return 1;
if (strcmp(argv[i], "-?") == 0) return 1;
elog(LOG_CRIT, "Unrecognized option: '%s'", argv[i]);
}
return 1;
}
return 0;
}
See more files for this project here