ossp-pkg/rc/rc_cliopt.c
/* OSSP rc - Run-Command Processor
** Copyright (c) 2002-2003 Ralf S. Engelschall
** Copyright (c) 2002-2003 Cable & Wireless Deutschland GmbH
** Copyright (c) 2002-2003 The OSSP Project <http://www.ossp.org/>
**
** This file is part of OSSP rc, a portable run-command processor
** which can be found at http://www.ossp.org/pkg/lib/rc/
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** 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.
**
** rc_cliopt.c: Run-Command Processor ISO C source file
*/
#include <stdlib.h>
#include <string.h>
#include "rc.h"
#include "rc_cliopt.h"
#include "rc_const.h"
#include "rc_config.h"
#include "popt.h" /* OSSP popt options library */
/***************************************
* clioptNew(void) *
* Construct a command line option *
***************************************/
rc_cliopt_t *clioptNew(void)
{
rc_cliopt_t *pRetobj = calloc(1, sizeof (rc_cliopt_t));
if (pRetobj) {
pRetobj->m_pszOptuples = calloc(RC_NUMOPTS, sizeof (char *));
if (!pRetobj->m_pszOptuples)
RC_THROW(RC_ERR_MEM);
}
else
RC_THROW(RC_ERR_MEM);
return(pRetobj);
/* assert(s_pBintab == NULL); */ /* Error if constructed already */
/* s_pBintab = malloc(sizeof(*s_pBintab));*/ /* Allocate a cliopt instance */
/* if (!s_pBintab)
return(RC_THROW(RC_ERR_MEM));
s_pBintab->pOptlist = malloc(sizeof(*s_pBintab->pOptlist));*/
/*FIXME optNew((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/
/* s_pBintab->pOptlist->pvData = NULL;
s_pBintab->pOptlist->pvNext = NULL;*/
}
/***************************************
* clioptPrintusage(rc_cliopt_t *) *
* Print usage to command line stderr *
***************************************/
rc_return_t clioptPrintusage(rc_cliopt_t *this)
{
popt_printusage(m_Optcon, stderr, 0);
return(RC_THROW(RC_OK));
}
/***************************************
* clioptGetXXX(rc_cliopt_t *) *
* clioptSetXXX(rc_cliopt_t *) *
* Command line option accessors *
***************************************/
const char *clioptGetval(rc_cliopt_t *this, rc_opt_t Optname)
{
if (!(Optname < RC_NUMOPTS)) /* Validate option range */
RC_THROW(RC_ERR_USE);
return((const char *)this->m_pszOptuples[Optname]);
}
const char *clioptGetrcfile(rc_cliopt_t *this)
{
if (!this->m_szRcfile)
RC_THROW(RC_ERR_USE);
return((const char *)this->m_szRcfile);
}
const char **clioptGetsecs(rc_cliopt_t *this)
{
if (!this->m_pszSecs)
RC_THROW(RC_ERR_USE);
return((const char **)this->m_pszSecs);
}
rc_return_t clioptSetval(rc_cliopt_t *this, rc_opt_t Optname, const char *kszOptval)
{
if (!(Optname < RC_NUMOPTS)) /* Validate option range */
return(RC_THROW(RC_ERR_USE));
if (!(kszOptval)) /* Validate string value */
return(RC_THROW(RC_ERR_USE));
if (!(m_pszOptuples[Optname] = strdup(kszOptval)))
return(RC_THROW(RC_ERR_MEM));
return(RC_THROW(RC_OK));
}
rc_return_t clioptSetrcfile(rc_cliopt_t *this, const char *kszRc)
{
if (this->m_szRcfile) /* Warn on overwrites */
RC_THROW(RC_WRN_OWR);
if (kszRc)
this->m_szRcfile = strdup(kszRc);
else
return(RC_THROW(RC_ERR_USE)); /* Incoming string is NULL? */
return(RC_THROW(RC_OK));
}
rc_return_t clioptSetsecs(rc_cliopt_t *this, const char **pkszSecs)
{
ex_t Except;
assert (pkszSecs); /* IF NULL, its broken */
if (this->m_pszSecs) /* Warn on overwrites */
RC_THROW(RC_WRN_OWR);
try {
this->m_pszSecs = vectorCopy(pkszSecs);
}
catch(Except)
rethrow;
return(RC_THROW(RC_OK));
}
/****************************************************
* clioptProcess(rc_cliopt_t *, int, const char *) *
* Switch through available options *
* processing the corresponding option *
* and update option table accordingly *
****************************************************/
rc_return_t clioptProcess(rc_cliopt_t *this, int cliOption, const char *kszArg)
{
switch (cliOption) {
/* Begin concrete (digital) options */
case RC_USE_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Usage */
case RC_DBG_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Debug */
case RC_VER_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Version */
case RC_EVL_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Eval */
case RC_HLP_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Help */
case RC_INF_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Info */
case RC_LBL_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Label */
case RC_PRN_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Print */
case RC_PAR_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Print */
case RC_SIL_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Silent */
case RC_RAW_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Raw */
case RC_VRB_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Verbose */
case RC_EXC_VAL:
clioptSetval(this, cliOption, RC_DEF_ON); break; /* Exec */
/* Begin abstract (nondigital) options */
case RC_LOC_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Locations */
case RC_CNF_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Conf file */
case RC_FNC_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Func file */
case RC_QRY_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Format */
case RC_TMP_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Temp dir */
case RC_OWN_VAL:
clioptSetval(this, cliOption, kszArg); break; /* User name */
case RC_GRP_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Group name */
case RC_MSK_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Umask */
case RC_ASS_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Assignregex */
case RC_DEF_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Labelregex */
case RC_REF_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Refregex */
case RC_PRM_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Paramregex */
case RC_TRM_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Termregex */
case RC_NCF_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Configname */
case RC_CMN_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Commonname */
case RC_DFL_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Defaultname */
case RC_ERR_VAL:
clioptSetval(this, cliOption, kszArg); break; /* Errorname */
default : break;
}
return(RC_THROW(RC_OK));
}
/********************************************************
* clioptParseopts(rc_cliopt_t *, int, const char **) *
* Parse command line options *
********************************************************/
rc_return_t clioptParseopts(rc_cliopt_t *this, int nArgs, const char *szVector[])
{
ex_t Except;
char cliOpt = 0; /* For argument parsing */
m_Optcon = popt_getcontext(NULL, nArgs, szVector, m_pOptable, 0);
popt_setotheroptionhelp(m_Optcon, "<rcfile> <sections [args]>");
if (nArgs < 2) { /* Allow the user to enter just one option, -h z.B. */
fprintf(stderr, RC_LST_TEXT);
popt_printusage(m_Optcon, stderr, 0);
return(RC_THROW(RC_ERR_USE));
}
/* Now do options processing */
while ((cliOpt = popt_getnextopt(m_Optcon)) >= 0) {/* Loop, each time */
try { /* eating a new option */
clioptProcess(this, cliOpt, popt_getoptarg(m_Optcon));
}
catch(Except) /* Error condition probably deserves attention */
rethrow;
}
if (cliOpt < -1) { /* The option given was not found in the index */
fprintf(stderr, "%s: %s\n",
popt_badoption(m_Optcon, POPT_BADOPTION_NOALIAS),
popt_strerror(cliOpt));
return(RC_THROW(RC_ERR_USE));
}
return(RC_THROW(RC_OK));
}
/******************************************
* clioptParseargs(rc_cliopt_t *) *
* Parse command line rc file and sections *
******************************************/
rc_return_t clioptParseargs(rc_cliopt_t *this)
{
ex_t Except;
/* Use popt as a transport to read the user specified rcfile and sections */
try {
clioptSetrcfile(this, popt_getarg(m_Optcon));
clioptSetsecs(this, popt_getargs(m_Optcon));
}
catch(Except)
rethrow; /* Our generic response */
return(RC_THROW(RC_OK));
}
/***************************************
* clioptDelete(rc_cliopt_t *) *
* Destruct a command line option *
***************************************/
rc_return_t clioptDelete(rc_cliopt_t *this)
{
int i = 0;
/* ex_t Except;
assert(s_pBintab);*/ /* Error if not constructed */
/* try {
clioptRemall();*/ /* Removes ALL list nodes */
/*FIXME optDelete((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/
/* free(s_pBintab->pOptlist);*/ /* Deallocate option list */
/* free(s_pBintab);*/ /* Deallocate cliopt and */
/* s_pBintab = NULL;*/ /* clear its reference */
/* }
catch(Except)
rethrow;
*/
popt_freecontext(m_Optcon); /* Free the popt context */
if (m_pszOptuples) {
for (i = 0; i < RC_NUMOPTS; i++) { /* Free the tuples themselves */
if (m_pszOptuples[i]) {
free(m_pszOptuples[i]);
m_pszOptuples[i] = NULL;
}
}
free(this->m_pszOptuples);
this->m_pszOptuples = NULL;
}
if (this->m_szRcfile) { /* Free the rc file arg */
free(this->m_szRcfile);
this->m_szRcfile = NULL;
}
if (this->m_pszSecs) { /* Free the section name arg */
vectorDel(this->m_pszSecs);
this->m_pszSecs = NULL;
}
free(this);
return(RC_THROW(RC_OK));
}