123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /* LIBDGL -- a Directed Graph Library implementation
- * Copyright (C) 2002 Roberto Micarelli
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /* best view tabstop=4
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "opt.h"
- static int _ParseLongOption(GnoOption_s * pOpt, char *pszArg)
- {
- char *pszLong;
- char *pszPar;
- char *pszMatch = NULL;
- int nret;
- if (pOpt->pszLong == NULL) {
- return 0;
- }
- pszLong = strdup(pOpt->pszLong);
- if ((pszPar = strchr(pszArg, '=')) != NULL) {
- *pszPar = 0;
- }
- pszMatch = strdup(pszArg);
- if (pszPar)
- *pszPar++ = '=';
- if (strcmp(pszLong, pszMatch + 2) == 0) {
- /* * mandatory parameter not found
- * */
- if (pszPar == NULL) {
- nret = -1;
- goto free_and_exit;
- }
- if (pOpt->ppszValue) {
- if (pOpt->ppszValue[0])
- free(pOpt->ppszValue[0]);
- pOpt->ppszValue[0] = strdup(pszPar);
- }
- nret = 1;
- goto free_and_exit;
- }
- nret = 0;
- free_and_exit:
- free(pszLong);
- free(pszMatch);
- return nret;
- }
- static int _ParseLongSwitch(GnoOption_s * pOpt, char *pszArg)
- {
- if (pOpt->pszLong == NULL) {
- return 0;
- }
- if (strcmp(pOpt->pszLong, pszArg + 2) == 0) {
- if (pOpt->pfValue)
- *pOpt->pfValue = True;
- return 1;
- }
- return 0;
- }
- static int _ParseShortOption(GnoOption_s * pOpt, char *pszArg, char *pszPar)
- {
- char *pszShort;
- int ich;
- if (pOpt->pszShort == NULL)
- return 0;
- pszShort = strdup(pOpt->pszShort);
- for (ich = 1; pszArg[ich]; ich++) {
- if (pszShort[0] == pszArg[ich]) {
- if (pszPar == NULL || pszPar[0] == 0) {
- free(pszShort);
- return -1;
- }
- if (pszPar[0] == '-' && pszPar[1] != 0) {
- free(pszShort);
- return -1;
- }
- if (pOpt->ppszValue) {
- if (pOpt->ppszValue[0])
- free(pOpt->ppszValue[0]);
- pOpt->ppszValue[0] = strdup(pszPar);
- }
- free(pszShort);
- return 2;
- }
- }
- free(pszShort);
- return 0;
- }
- static int _ParseShortSwitch(GnoOption_s * pOpt, char *pszArg)
- {
- int ich;
- if (pOpt->pszShort == NULL)
- return 0;
- for (ich = 1; pszArg[ich]; ich++) {
- if (pOpt->pszShort[0] == pszArg[ich]) {
- if (pOpt->pfValue)
- *pOpt->pfValue = True;
- return 1;
- }
- }
- return 0;
- }
- /***********************************************************************
- * CALLBACKS
- **********************************************************************/
- /***********************************************************************
- * PUBLIC FUNCTIONS
- **********************************************************************/
- /*@*--------------------------------------------------------------------
- * @func: GnoParse()
- * @descr: Parse argc, argv against the option array and setup option
- * values in the array.
- *
- * @args: I: argc = count of argv entries
- * I: argv -> array of pointer to string
- * I: pOpt -> option array pointer
- *
- * @ret: The number of 'orphan' entries found in the argv.
- * @see: GnoOption_s
- *
- * @notes: The argv array will be modified: each argv entry that contains a
- * recognized option ( '-.' or '--...' ) or each entry recognized as
- * a parametric option parameter, will be set to NULL.
- * Thus, at the function return the argv entries not set to NULL are
- * those of orphan entries (those not related to any option).
- * The user can then scan argv to find out orphans.
- * However the number of argv entries will not be altered.
- *
- *--------------------------------------------------------------------*/
- int GnoParse(int argc, char **argv, GnoOption_s * pOpt)
- {
- char *pszArgv;
- char *pszArgvNxt;
- int iArg, iOpt, cOrphan = 0;
- int nret, cret;
- Boolean fParseError = False;
- /* * this first loop setup default values
- * * strdup is used for non-switch options
- * * to make life easier when freeing the field
- * */
- for (iOpt = 0; pOpt[iOpt].pszShort || pOpt[iOpt].pszLong; iOpt++) {
- if (pOpt[iOpt].nFlg & GNO_FLG_SWITCH) {
- if (pOpt[iOpt].pfValue) {
- pOpt[iOpt].pfValue[0] = pOpt[iOpt].fDef;
- }
- }
- else {
- if (pOpt[iOpt].pszDef) {
- if (pOpt[iOpt].ppszValue) {
- pOpt[iOpt].ppszValue[0] = strdup(pOpt[iOpt].pszDef);
- }
- }
- else {
- if (pOpt[iOpt].ppszValue) {
- pOpt[iOpt].ppszValue[0] = NULL;
- }
- }
- }
- }
- /* * for each arg in argv lookup the matching options
- * */
- for (iArg = 0, pszArgv = NULL;
- iArg < argc && (pszArgv = strdup(argv[iArg])) != NULL;
- iArg++, free(pszArgv), pszArgv = NULL) {
- if (pszArgv[0] == '-' && pszArgv[1] == '-' && pszArgv[2]) { /* long style */
- for (iOpt = 0;
- (pOpt[iOpt].pszShort || pOpt[iOpt].pszLong) && argv[iArg];
- iOpt++) {
- if (pOpt[iOpt].pszLong) {
- if (pOpt[iOpt].nFlg & GNO_FLG_SWITCH) {
- nret = _ParseLongSwitch(&pOpt[iOpt], pszArgv);
- }
- else {
- nret = _ParseLongOption(&pOpt[iOpt], pszArgv);
- }
- if (nret < 0) {
- fprintf(stderr,
- "parse option: syntax error at <%s>\n",
- pszArgv);
- fParseError = True;
- }
- if (nret == 1) {
- argv[iArg] = NULL;
- }
- }
- }
- if (argv[iArg]) {
- fprintf(stderr, "parse option: <%s> is out of scope\n",
- pszArgv);
- fParseError = True;
- }
- }
- else if (argv[iArg][0] == '-' && argv[iArg][1]) { /* short style */
- if (iArg + 1 < argc) {
- pszArgvNxt = strdup(argv[iArg + 1]);
- }
- else {
- pszArgvNxt = NULL;
- }
- for (cret = iOpt = 0;
- pOpt[iOpt].pszShort || pOpt[iOpt].pszLong; iOpt++) {
- if (pOpt[iOpt].pszShort) {
- if (pOpt[iOpt].nFlg & GNO_FLG_SWITCH) {
- nret = _ParseShortSwitch(&pOpt[iOpt], pszArgv);
- }
- else {
- nret =
- _ParseShortOption(&pOpt[iOpt], pszArgv,
- pszArgvNxt);
- }
- if (nret < 0) {
- fprintf(stderr,
- "parse option: syntax error at <%s>\n",
- pszArgv);
- fParseError = True;
- }
- else {
- cret = (nret > cret) ? nret : cret;
- }
- }
- }
- if (pszArgvNxt) {
- free(pszArgvNxt);
- }
- if (cret == 1) {
- argv[iArg] = NULL;
- }
- else if (cret == 2) {
- argv[iArg++] = NULL;
- argv[iArg] = NULL;
- }
- }
- else {
- cOrphan++;
- }
- }
- if (pszArgv)
- free(pszArgv);
- return (fParseError == True) ? -1 : cOrphan;
- }
- /*@*--------------------------------------------------------------------
- * @func: GnoFree()
- * @descr: Free resource previously created with a call to GnoParse()
- *
- * @args: I: pOpt -> option array pointer
- *
- * @see: GnoOption_s, GnoParse()
- *
- *--------------------------------------------------------------------*/
- void GnoFree(GnoOption_s * pOpt)
- {
- int iOpt;
- for (iOpt = 0; pOpt[iOpt].pszShort || pOpt[iOpt].pszLong; iOpt++) {
- if (pOpt[iOpt].ppszValue) {
- if (pOpt[iOpt].ppszValue[0]) {
- free(pOpt[iOpt].ppszValue[0]);
- pOpt[iOpt].ppszValue[0] = NULL;
- }
- }
- }
- }
- /*@*--------------------------------------------------------------------
- * @func: GnoHelp()
- * @descr: Print a brief option's help on the standard error
- *
- * @args: I: pszHead -> help header string
- *
- * @args: I: pOpt -> option array pointer
- *
- * @see: GnoOption_s
- *
- *--------------------------------------------------------------------*/
- void GnoHelp(char *pszHead, GnoOption_s * pOpt)
- {
- int iOpt;
- fprintf(stderr, "%s\n", (pszHead) ? pszHead : "options");
- for (iOpt = 0; pOpt[iOpt].pszShort || pOpt[iOpt].pszLong; iOpt++) {
- if (pOpt[iOpt].nFlg & GNO_FLG_SWITCH) {
- if (pOpt[iOpt].pszShort) {
- fprintf(stderr, "-%s ", pOpt[iOpt].pszShort);
- }
- if (pOpt[iOpt].pszLong) {
- fprintf(stderr, "--%s", pOpt[iOpt].pszLong);
- }
- fprintf(stderr, "\n\t%s\n", (pOpt[iOpt].pszDescr)
- ? pOpt[iOpt].pszDescr : "No description available.");
- }
- else {
- if (pOpt[iOpt].pszShort) {
- fprintf(stderr, "-%s ", pOpt[iOpt].pszShort);
- fprintf(stderr, "<value> ");
- }
- if (pOpt[iOpt].pszLong) {
- fprintf(stderr, "--%s", pOpt[iOpt].pszLong);
- fprintf(stderr, "=<value>");
- }
- fprintf(stderr, "\n\t%s\n", (pOpt[iOpt].pszDescr)
- ? pOpt[iOpt].pszDescr : "No description available.");
- }
- }
- }
- /******************************* END OF FILE **************************/
|