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

📄 argv.c

📁 dtelent是开源的开发项目
💻 C
字号:
/* argv.c
 * Copyright (C) 1998-2005 David Cole
 *
 * Implement getopt() like argv/argc parsing
 */
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "argv.h"

/* Split a string into argc/argv
 *
 * Args:
 * str -      the argument string. Will be modified in place
 * argv	-     array that will be filled	with pointers to individual arguments
 * argvSize - number of elements in argv
 *
 * Returns number of arguments found (argc)
 *
 * Example of sh-like argument parsing:
 *
 *    in:  \a\ \c
 *    out: a c
 *    in:  "\a\ \c"
 *    out: \a\ \c
 *    in:  '\a\ \c'
 *    out: \a\ \c
 *    in:  \r\ Hallo" "\rLajos'\'"\""
 *    out: r Hallo \rLajos\"
 */
int getoptInit (char* str, char** argv, int argvSize)
{
    int argc, state, strsep;
    char *to;

    for (argc= 0, to= str, state= 0; argc <= argvSize && *str; ++str) {
	if (state==0) {
	    if (isspace(*str)); /* do nothing */
	    else if (*str=='"' || *str=='\'') {
		argv[argc]= to; strsep= *str; state= 3;
	    } else if (*str=='\\') state= 2;
	    else {
		argv[argc]= to; *to++ = *str; state= 1;
	    }

	} else if (state==1) {
	    if (isspace(*str)) {
		++argc; *to++ = '\0'; state= 0;
	    } else if (*str=='"' || *str=='\'') { strsep= *str; state= 3; }
	    else if (*str=='\\') state= 2;
	    else { *to++ = *str; }

	} else if (state==2) {
	    *to++ = *str;
	    state = 1;

	} else if (state==3) {
	    if (*str==strsep) state= 1;
	    else if (strsep=='"' && *str=='\\') state= 4;
	    else { *to++ = *str; }

	} else if (state==4) {
	    if (*str!='"' && *str!='\\') *to++ = '\\';
	    *to++ = *str;
	    state = 3;
	}
    }
    if (state!=0) { ++argc; *to= '\0'; };

    return argc;
}

/* This variable is part of the getopt() functionality
 */
OptRet opt;

/* Iterates	over argc/argv,	returning arguments	in the order that they
 * appear in argv.	The	first time that	the	function is	called,	it
 * stores the passed argc/argv,	these are then used	for	each
 * subsequent call.
 *
 * Args:
 * argcInit	- number of	arguments in argv
 * argvInit	- array	of string arguments
 * opts	-	  describes	argument structure;
 *				<c>	 - <c> is a	switch (no associated data)
 *				<c>: - <c> is an argument with associated data
 *
 * Returns the next	valid argument found in	argv.  If argument found
 * does	not appear in opts, '?' is returned. At end of argv or
 * non-argument	encountered, EOF is returned.
 */
int getopt (int argcInit, char* argvInit[], const char* opts)
{
	static int argc;			/* iterate over	argc */
	static char** argv;			/* iterate over	argv */

	int c;					/* the next command line argument */
	const char *str, *optbeg, *optend;	/* scan	the option string */
	const char *arg;			/* scan	the argument string */
	int arglen, optlen, found, optno;

	if (argv == NULL) {
		/* Initialise getopt if	this is	the first time we have been
		 * called.
		 */
		argc = argcInit;
		argv = argvInit;
		opt.optind = -1;
	}

	/* Skip	to the next	argument, return EOF if	there are no more.
	 */
	opt.optind++;
	if (opt.optind == argc)	{
		argv = NULL;
		return EOF;
	}

	/* Terminate argument processing if the	next argument does not
	 * start with either a '-' or a	'/'.
	 */
	if (*argv[opt.optind] != '/' && *argv[opt.optind] != '-') {
		argv = NULL;
		return EOF;
	}

	/* Get the argument, if	it is '\0', then we have an error.
	 */
	arg = argv[opt.optind]+1;
	c = toupper (arg[0]);
	arglen = strlen (arg);
	if (c == 0)	{
		return '?';
	}
	/* Find	the argument in	the option string, if not found, we have
	 * an error.
	 */
	for (found= 0, str= opts, optno= 1; ! found && *str != '\0'; ) {
	    if (*str=='(') {
		optbeg = str+1;
		optend = strchr (optbeg, ')');
		if (optend) {
		    str = optend + 1;
		} else {             /* This should not be happen */
		    optend = str + strlen (str);
		    str = optend;
		}
		optlen = (int)(optend - optbeg);
		found= arglen>=optlen &&
		       (arg[optlen]=='\x0' || arg[optlen]=='=') &&
		       strnicmp (optbeg, arg, optlen)==0;
	    } else {
		found= toupper(*str)==c;
		if (found) {
		    optbeg = str;
		    optend = str+1;
		    optlen = (int)(optend-optbeg);
		}
		++str;
	    }
	    if (! found) {
		++optno;
		if (*str==':') ++str;
	    }
	}
	if (! found) {
		return '?';
	}

	if (*str == ':') {			    /* option with value */
	    if (optlen>1 && arg[optlen]=='=') {     /* /LongOpt=Vale     */
		opt.optarg = (char *)(arg + optlen + 1);

	    } else if (optlen==1 && arg[1]!='\0') { /* /XValue */
		opt.optarg = (char *)(arg + optlen);

	    } else {                                /* /Option Value */
		if (opt.optind+1 < argc ) 
		    opt.optarg = argv[++opt.optind];
		else {
		    /* error if the arguments are ended */
		    return '?';
		}
	    }
	}

	/* Tell	caller which argument we found
	 */
	if (optlen==1) return c;
	else           return GETOPT_LONGOPT + optno;
}

⌨️ 快捷键说明

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