⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 popt.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/** \ingroup popt * \file popt/popt.c *//* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING   file accompanying popt source distributions, available from   ftp://ftp.rpm.org/pub/rpm/dist */#undef	MYDEBUG#include "system.h"#if HAVE_MATH_H#include <math.h>#endif#if HAVE_FLOAT_H#include <float.h>#endif#include "findme.h"#include "poptint.h"#ifdef	MYDEBUG/*@unchecked@*/int _popt_debug = 0;#endif#ifndef HAVE_STRERRORstatic char * strerror(int errno) {    extern int sys_nerr;    extern char * sys_errlist[];    if ((0 <= errno) && (errno < sys_nerr))	return sys_errlist[errno];    else	return POPT_("unknown errno");}#endif#ifdef MYDEBUG/*@unused@*/ static void prtcon(const char *msg, poptContext con){    if (msg) fprintf(stderr, "%s", msg);    fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n",	con, con->os,	(con->os->nextCharArg ? con->os->nextCharArg : ""),	(con->os->nextArg ? con->os->nextArg : ""),	con->os->next,	(con->os->argv && con->os->argv[con->os->next]		? con->os->argv[con->os->next] : ""));}#endifvoid poptSetExecPath(poptContext con, const char * path, int allowAbsolute){    con->execPath = _free(con->execPath);    con->execPath = xstrdup(path);    con->execAbsolute = allowAbsolute;    /*@-nullstate@*/ /* LCL: con->execPath can be NULL? */    return;    /*@=nullstate@*/}static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)	/*@globals internalState@*/	/*@modifies internalState@*/{    if (opt != NULL)    for (; opt->longName || opt->shortName || opt->arg; opt++) {	if (opt->arg == NULL) continue;		/* XXX program error. */	if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {	    /* Recurse on included sub-tables. */	    invokeCallbacksPRE(con, opt->arg);	} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&		   (opt->argInfo & POPT_CBFLAG_PRE))	{   /*@-castfcnptr@*/	    poptCallbackType cb = (poptCallbackType)opt->arg;	    /*@=castfcnptr@*/	    /* Perform callback. */	    /*@-moduncon -noeffectuncon @*/	    cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);	    /*@=moduncon =noeffectuncon @*/	}    }}static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)	/*@globals internalState@*/	/*@modifies internalState@*/{    if (opt != NULL)    for (; opt->longName || opt->shortName || opt->arg; opt++) {	if (opt->arg == NULL) continue;		/* XXX program error. */	if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {	    /* Recurse on included sub-tables. */	    invokeCallbacksPOST(con, opt->arg);	} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&		   (opt->argInfo & POPT_CBFLAG_POST))	{   /*@-castfcnptr@*/	    poptCallbackType cb = (poptCallbackType)opt->arg;	    /*@=castfcnptr@*/	    /* Perform callback. */	    /*@-moduncon -noeffectuncon @*/	    cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);	    /*@=moduncon =noeffectuncon @*/	}    }}static void invokeCallbacksOPTION(poptContext con,				  const struct poptOption * opt,				  const struct poptOption * myOpt,				  /*@null@*/ const void * myData, int shorty)	/*@globals internalState@*/	/*@modifies internalState@*/{    const struct poptOption * cbopt = NULL;    if (opt != NULL)    for (; opt->longName || opt->shortName || opt->arg; opt++) {	if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {	    /* Recurse on included sub-tables. */	    if (opt->arg != NULL)	/* XXX program error */		invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty);	} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&		  !(opt->argInfo & POPT_CBFLAG_SKIPOPTION)) {	    /* Save callback info. */	    cbopt = opt;	} else if (cbopt != NULL &&		   ((myOpt->shortName && opt->shortName && shorty &&			myOpt->shortName == opt->shortName) ||		    (myOpt->longName && opt->longName &&		/*@-nullpass@*/		/* LCL: opt->longName != NULL */			!strcmp(myOpt->longName, opt->longName)))		/*@=nullpass@*/		   )	{   /*@-castfcnptr@*/	    poptCallbackType cb = (poptCallbackType)cbopt->arg;	    /*@=castfcnptr@*/	    const void * cbData = (cbopt->descrip ? cbopt->descrip : myData);	    /* Perform callback. */	    if (cb != NULL) {	/* XXX program error */		/*@-moduncon -noeffectuncon @*/		cb(con, POPT_CALLBACK_REASON_OPTION, myOpt,			con->os->nextArg, cbData);		/*@=moduncon =noeffectuncon @*/	    }	    /* Terminate (unless explcitly continuing). */	    if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE))		return;	}    }}poptContext poptGetContext(const char * name, int argc, const char ** argv,			   const struct poptOption * options, int flags){    poptContext con = malloc(sizeof(*con));    if (con == NULL) return NULL;	/* XXX can't happen */    memset(con, 0, sizeof(*con));    con->os = con->optionStack;    con->os->argc = argc;    /*@-dependenttrans -assignexpose@*/	/* FIX: W2DO? */    con->os->argv = argv;    /*@=dependenttrans =assignexpose@*/    con->os->argb = NULL;    if (!(flags & POPT_CONTEXT_KEEP_FIRST))	con->os->next = 1;			/* skip argv[0] */    con->leftovers = calloc( (argc + 1), sizeof(*con->leftovers) );    /*@-dependenttrans -assignexpose@*/	/* FIX: W2DO? */    con->options = options;    /*@=dependenttrans =assignexpose@*/    con->aliases = NULL;    con->numAliases = 0;    con->flags = flags;    con->execs = NULL;    con->numExecs = 0;    con->finalArgvAlloced = argc * 2;    con->finalArgv = calloc( con->finalArgvAlloced, sizeof(*con->finalArgv) );    con->execAbsolute = 1;    con->arg_strip = NULL;    if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))	con->flags |= POPT_CONTEXT_POSIXMEHARDER;    if (name) {	char * t = malloc(strlen(name) + 1);	if (t) con->appName = strcpy(t, name);    }    /*@-internalglobs@*/    invokeCallbacksPRE(con, con->options);    /*@=internalglobs@*/    return con;}static void cleanOSE(/*@special@*/ struct optionStackEntry *os)	/*@uses os @*/	/*@releases os->nextArg, os->argv, os->argb @*/	/*@modifies os @*/{    os->nextArg = _free(os->nextArg);    os->argv = _free(os->argv);    os->argb = PBM_FREE(os->argb);}/*@-boundswrite@*/void poptResetContext(poptContext con){    int i;    if (con == NULL) return;    while (con->os > con->optionStack) {	cleanOSE(con->os--);    }    con->os->argb = PBM_FREE(con->os->argb);    con->os->currAlias = NULL;    con->os->nextCharArg = NULL;    con->os->nextArg = NULL;    con->os->next = 1;			/* skip argv[0] */    con->numLeftovers = 0;    con->nextLeftover = 0;    con->restLeftover = 0;    con->doExec = NULL;    if (con->finalArgv != NULL)    for (i = 0; i < con->finalArgvCount; i++) {	/*@-unqualifiedtrans@*/		/* FIX: typedef double indirection. */	con->finalArgv[i] = _free(con->finalArgv[i]);	/*@=unqualifiedtrans@*/    }    con->finalArgvCount = 0;    con->arg_strip = PBM_FREE(con->arg_strip);    /*@-nullstate@*/	/* FIX: con->finalArgv != NULL */    return;    /*@=nullstate@*/}/*@=boundswrite@*//* Only one of longName, shortName should be set, not both. *//*@-boundswrite@*/static int handleExec(/*@special@*/ poptContext con,		/*@null@*/ const char * longName, char shortName)	/*@uses con->execs, con->numExecs, con->flags, con->doExec,		con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/	/*@modifies con @*/{    poptItem item;    int i;    if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */	return 0;    for (i = con->numExecs - 1; i >= 0; i--) {	item = con->execs + i;	if (longName && !(item->option.longName &&			!strcmp(longName, item->option.longName)))	    continue;	else if (shortName != item->option.shortName)	    continue;	break;    }    if (i < 0) return 0;    if (con->flags & POPT_CONTEXT_NO_EXEC)	return 1;    if (con->doExec == NULL) {	con->doExec = con->execs + i;	return 1;    }    /* We already have an exec to do; remember this option for next       time 'round */    if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {	con->finalArgvAlloced += 10;	con->finalArgv = realloc(con->finalArgv,			sizeof(*con->finalArgv) * con->finalArgvAlloced);    }    i = con->finalArgvCount++;    if (con->finalArgv != NULL)	/* XXX can't happen */    {	char *s  = malloc((longName ? strlen(longName) : 0) + 3);	if (s != NULL) {	/* XXX can't happen */	    if (longName)		sprintf(s, "--%s", longName);	    else		sprintf(s, "-%c", shortName);	    con->finalArgv[i] = s;	} else	    con->finalArgv[i] = NULL;    }    /*@-nullstate@*/	/* FIX: con->finalArgv[] == NULL */    return 1;    /*@=nullstate@*/}/*@=boundswrite@*//* Only one of longName, shortName may be set at a time */static int handleAlias(/*@special@*/ poptContext con,		/*@null@*/ const char * longName, char shortName,		/*@exposed@*/ /*@null@*/ const char * nextCharArg)	/*@uses con->aliases, con->numAliases, con->optionStack, con->os,		con->os->currAlias, con->os->currAlias->option.longName @*/	/*@modifies con @*/{    poptItem item = con->os->currAlias;    int rc;    int i;    if (item) {	if (longName && (item->option.longName &&		!strcmp(longName, item->option.longName)))	    return 0;	if (shortName && shortName == item->option.shortName)	    return 0;    }    if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */	return 0;    for (i = con->numAliases - 1; i >= 0; i--) {	item = con->aliases + i;	if (longName && !(item->option.longName &&			!strcmp(longName, item->option.longName)))	    continue;	else if (shortName != item->option.shortName)	    continue;	break;    }    if (i < 0) return 0;    if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)	return POPT_ERROR_OPTSTOODEEP;/*@-boundsread@*/    if (nextCharArg && *nextCharArg)	con->os->nextCharArg = nextCharArg;/*@=boundsread@*/    con->os++;    con->os->next = 0;    con->os->stuffed = 0;    con->os->nextArg = NULL;    con->os->nextCharArg = NULL;    con->os->currAlias = con->aliases + i;    rc = poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv,		&con->os->argc, &con->os->argv);    con->os->argb = NULL;    return (rc ? rc : 1);}/*@-bounds -boundswrite @*/static int execCommand(poptContext con)	/*@globals internalState @*/	/*@modifies internalState @*/{    poptItem item = con->doExec;    const char ** argv;    int argc = 0;    int rc;    if (item == NULL) /*XXX can't happen*/	return POPT_ERROR_NOARG;    if (item->argv == NULL || item->argc < 1 ||	(!con->execAbsolute && strchr(item->argv[0], '/')))	    return POPT_ERROR_NOARG;    argv = malloc(sizeof(*argv) *			(6 + item->argc + con->numLeftovers + con->finalArgvCount));    if (argv == NULL) return POPT_ERROR_MALLOC;	/* XXX can't happen */    if (!strchr(item->argv[0], '/') && con->execPath) {	char *s = alloca(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));	sprintf(s, "%s/%s", con->execPath, item->argv[0]);	argv[argc] = s;    } else {	argv[argc] = findProgramPath(item->argv[0]);    }    if (argv[argc++] == NULL) return POPT_ERROR_NOARG;    if (item->argc > 1) {	memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1));	argc += (item->argc - 1);    }    if (con->finalArgv != NULL && con->finalArgvCount > 0) {	memcpy(argv + argc, con->finalArgv,		sizeof(*argv) * con->finalArgvCount);	argc += con->finalArgvCount;    }    if (con->leftovers != NULL && con->numLeftovers > 0) {#if 0	argv[argc++] = "--";#endif	memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);	argc += con->numLeftovers;    }    argv[argc] = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -