Files
m241Neelima/components/ip_net2-6.9/ipcom/src/ipcom_getopt.c
T
2026-07-30 11:19:44 +05:30

393 lines
12 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_getopt.c,v $ $Revision: 1.27.70.1 $
* $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_getopt.c,v $
* $Author: svc-cmnet $ $Date: 2013-03-13 07:45:17 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 BSD COPYRIGHT
****************************************************************************
* Interpeak getopt() based on a NetBSD version. The code bas been rewritten
* to support reentrant function versions and long options, e.g. '-name'.
*
* $NetBSD: getopt.c,v 1.17 2000/01/22 22:19:19 mycroft Exp $
* Copyright (c) 1987, 1993, 1994
* 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:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipcom_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_getopt.h"
#include "ipcom_clib.h"
/*
****************************************************************************
* 4 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 5 DEFINES
****************************************************************************
*/
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_STATIC int ipcom_getopt_longopt(Ipcom_getopt *opt, char *name, char *delim);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/* Global IPCOM getopt data for the old non-reentrant getopt() functions. */
IP_PUBLIC Ipcom_getopt ipcom_getopt_data;
/*
****************************************************************************
* 9 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_getopt_longopt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_getopt_longopt(Ipcom_getopt *opt, char *name, char *delim)
{
int i, found;
struct Ipcom_getopt_longopt_struct *lopt;
if (!*name)
return -1;
found = -1;
for(i = 0, lopt = opt->long_options; lopt->name && *lopt->name; lopt++, i++)
{
if (ipcom_strncmp(lopt->name, name, (Ip_size_t)(delim - name)) == 0)
{
/* Exact match. */
if (ipcom_strlen(lopt->name) == (Ip_size_t)((Ip_ptrdiff_t)delim - (Ip_ptrdiff_t)name))
return i;
/* Partial match. */
if (found == -1)
found = i;
else
found = -2; /* ambiguous command */
}
}
return found;
}
/*
*===========================================================================
* ipcom_getopt_clear
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void
ipcom_getopt_clear_r(Ipcom_getopt *opt)
{
opt->opterr = 1;
opt->optind = 1;
opt->optopt = 0;
opt->optreset = 0;
opt->optarg = IP_NULL;
opt->place = EMSG; /* option letter processing */
opt->long_index = 0;
opt->long_only = 0;
opt->long_options = IP_NULL;
}
IP_PUBLIC void
ipcom_getopt_clear(void)
{
ipcom_getopt_clear_r(&ipcom_getopt_data);
}
/*
*===========================================================================
* ipcom_getopt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_getopt_r(int argc, char * const *argv, const char *optstring, Ipcom_getopt *opt)
{
const char *oli; /* option letter list index */
ip_assert(argv);
ip_assert(optstring);
if (opt->optreset || !*opt->place)
{
/* update scanning pointer */
opt->optreset = 0;
if (opt->optind >= argc)
goto emsg;
opt->place = argv[opt->optind];
if (*opt->place != '-' && *opt->place != '+')
goto emsg;
if (opt->place[1] && *++opt->place == '-' /* found "--" */
&& opt->place[1] == '\0')
{
++opt->optind;
emsg:
opt->place = EMSG;
return -1;
}
}
/* long option? */
if (opt->long_options != IP_NULL &&
(opt->long_only || *opt->place == '+'))
{
int indx;
char *delim;
/* allow an extra '-' before longoption name, i.e. '--optname' is ok. */
if (*opt->place == '-')
opt->place++;
for(delim = opt->place; *delim && *delim != '='; delim++)
{
/* NOP */
}
indx = ipcom_getopt_longopt(opt, opt->place, delim);
if (indx >= 0)
{
opt->long_index = indx;
++opt->optind;
opt->place = EMSG;
/* option does not take an argument. */
if (*delim != '=' && opt->long_options[indx].has_arg == 0)
opt->optarg = IP_NULL;
/* no more arguments but optional argument is ok. */
else if (*delim != '=' && argc == opt->optind && opt->long_options[indx].has_arg == 2)
opt->optarg = IP_NULL;
/* option requires an argument but no more exist. */
else if (*delim != '=' && argc <= opt->optind)
{
#if defined(IP_PORT_LAS) || IPCOM_USE_SHELL != IPCOM_SHELL_NONE
if (opt->opterr)
(void)ipcom_fprintf(ip_stderr, "%s: long option `%s' requires an argument"IP_LF,
argv[0], opt->long_options[indx].name);
#endif
return BADCH;
}
else
{
if (opt->long_options[indx].flag)
*opt->long_options[indx].flag = opt->long_options[indx].val;
if (*delim == '=')
opt->optarg = ++delim;
else
opt->optarg = argv[opt->optind++];
}
return 0;
}
else
{
/* A single option letter, check it with standard options. */
if (opt->place[1] == '\0' /*&& !opt->long_only*/)
goto single_letter;
#if IPCOM_USE_SHELL != IPCOM_SHELL_NONE
if (opt->opterr)
{
if (indx == -2)
ipcom_fprintf(ip_stderr, "%s: long option `%s' is ambiguous"IP_LF, argv[0], opt->place);
else
ipcom_fprintf(ip_stderr, "%s: unrecognized long option `%s'"IP_LF, argv[0], opt->place);
}
#endif
return BADCH;
}
/*goto argument;*/
}
/* option letter okay? */
single_letter:
if (!*opt->place)
{
#if IPCOM_USE_SHELL != IPCOM_SHELL_NONE
if (opt->opterr)
(void)ipcom_fprintf(ip_stderr, "%s: missing option name"IP_LF, argv[0]);
#endif
return BADCH;
}
if ((opt->optopt = (int)*opt->place++) == (int)':' ||
0 == (oli = ipcom_strchr(optstring, opt->optopt)))
{
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (opt->optopt == (int)'-')
return -1;
if (!*opt->place)
++opt->optind;
#if IPCOM_USE_SHELL != IPCOM_SHELL_NONE
if (opt->opterr && *optstring != ':')
(void)ipcom_fprintf(ip_stderr, "%s: illegal option -- %c"IP_LF, argv[0], opt->optopt);
#endif
return BADCH;
}
/* argument: */
/* don't need argument */
if (*++oli != ':')
{
opt->optarg = IP_NULL;
if (!*opt->place)
++opt->optind;
}
else
{
/* need an argument */
if (*opt->place) /* no white space */
opt->optarg = opt->place;
else if (argc <= ++opt->optind)
{
/* no arg */
opt->place = EMSG;
if (*optstring == ':')
return BADARG;
#if IPCOM_USE_SHELL != IPCOM_SHELL_NONE
if (opt->opterr)
(void)ipcom_fprintf(ip_stderr, "%s: option requires an argument -- %c"IP_LF, argv[0], opt->optopt);
#endif
return BADCH;
}
else
opt->optarg = argv[opt->optind]; /* white space */
opt->place = EMSG;
++opt->optind;
}
/* dump back option letter */
return opt->optopt;
}
/*
*===========================================================================
* ipcom_getopt
*===========================================================================
* Context:
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_getopt(int argc, char * const *argv, const char *optstring)
{
return ipcom_getopt_r(argc, argv, optstring, &ipcom_getopt_data);
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/