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

📄 getargs.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)getargs.c	2.28 00/05/20 Copyright 1985, 1988, 1995 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)getargs.c	2.28 00/05/20 Copyright 1985, 1988, 1995 J. Schilling";#endif#define	NEW/* *	Copyright (c) 1985, 1988, 1995 J. Schilling * *	1.3.88	 Start implementation of release 2 *//* *	Parse arguments on a command line. *	Format string specifier (appearing directly after flag name): *		''	BOOL *		'*'	string *		'?'	char *		'#'	number *		'&'	call function *		'+'	inctype		+++ NEU +++ *//* * 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, 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; see the file COPYING.  If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//* LINTLIBRARY */#include <mconfig.h>#include <standard.h>#include <getargs.h>#include <ctype.h>#include <vadefs.h>#include <strdefs.h>#include <schily.h>#define	NOARGS		  0	/* No more args			*/#define	NOTAFLAG	  1	/* Not a flag type argument	*/#define BADFLAG		(-1)	/* Not a valid flag argument	*/#define BADFMT		(-2)	/* Error in format string	*/#define NOTAFILE	(-3)	/* Seems to be a flag type arg	*/	int	_getargs __PR((int *, char *const **, const char *,							BOOL, va_list));LOCAL	int	dofile __PR((int *, char *const **, const char **));LOCAL	int	doflag __PR((int *, char *const **, const char *,						const char *, BOOL, va_list));LOCAL	int	dosflags __PR((const char *, const char *, BOOL, va_list));LOCAL	int	checkfmt __PR((const char *));LOCAL	int	checkeql __PR((const char *));LOCAL	va_list	va_dummy;LOCAL	char	fmtspecs[] = "#?*&+"; #define	isfmtspec(c)		(strchr(fmtspecs, c) != NULL)/*---------------------------------------------------------------------------||	get flags until a non flag type argument is reached|+---------------------------------------------------------------------------*//* VARARGS3 */#ifdef	PROTOTYPESint getargs(int *pac, char *const **pav, const char *fmt, ...)#elseint getargs(pac, pav, fmt, va_alist)	int	*pac;	char	**pav[];	char	*fmt;	va_dcl#endif{	va_list	args;	int	ret;#ifdef	PROTOTYPES	va_start(args, fmt);#else	va_start(args);#endif	ret = _getargs(pac, pav, fmt, TRUE, args);	va_end(args);	return (ret);}/*---------------------------------------------------------------------------||	get all flags on the command line, do not stop on files|+---------------------------------------------------------------------------*//* VARARGS3 */#ifdef	PROTOTYPESint getallargs(int *pac, char *const **pav, const char *fmt, ...)#elseint getallargs(pac, pav, fmt, va_alist)	int	*pac;	char	**pav[];	char	*fmt;	va_dcl#endif{	va_list	args;	int	ret;#ifdef	PROTOTYPES	va_start(args, fmt);#else	va_start(args);#endif	for (;; (*pac)--, (*pav)++) {		if ((ret = _getargs(pac, pav, fmt, TRUE, args)) != NOTAFLAG)			break;	}	va_end(args);	return (ret);}/*---------------------------------------------------------------------------||	get next non flag type argument (i.e. a file)|+---------------------------------------------------------------------------*/int getfiles(pac, pav, fmt)	int		*pac;	char *const	*pav[];	const char	*fmt;{	return (_getargs(pac, pav, fmt, FALSE, va_dummy));}/*---------------------------------------------------------------------------||	check args until the next non flag type argmument is reached|	*pac is decremented, *pav is incremented so that the|	non flag type argument is at *pav[0]||	return code:|		NOARGS		no more args|		NOTAFLAG	not a flag type argument|		BADFLAG		a non-matching flag type argument|		BADFMT		bad syntax in format string||+---------------------------------------------------------------------------*//*LOCAL*/ int _getargs(pac, pav, fmt, setargs, args)	register int		*pac;	register char	*const	**pav;		 const char	*fmt;		BOOL		setargs;		va_list		args;{	const	 char	*argp;		 int	ret;	for(; *pac > 0; (*pac)--, (*pav)++) {		argp = **pav;		ret = dofile(pac, pav, &argp);		if (ret != NOTAFILE)			return (ret);		ret = doflag(pac, pav, argp, fmt, setargs, args);		if (ret != NOTAFLAG)			return (ret);	}	return (NOARGS);}/*---------------------------------------------------------------------------|| check if *pargp is a file type argument|+---------------------------------------------------------------------------*/LOCAL int dofile(pac, pav, pargp)	register int		*pac;	register char *const	**pav;		 const char	**pargp;{	register const char	*argp = *pargp;	if (argp[0] == '-') {		/*		 * "-" is a special non flag type argument		 *     that usually means take stdin instead of a named file		 */		if (argp[1] == '\0')			return (NOTAFLAG);		/*		 * "--" is a prefix to take the next argument		 *	as non flag type argument		 * NOTE: Posix requires "--" to indicate the end of the		 *	 flags on the command line. But we are currently not		 *	 Posix.		 */		if (argp[1] == '-' && argp[2] == '\0') {			if (--(*pac) > 0) {				(*pav)++;				return (NOTAFLAG);			} else {				return (NOARGS);			}		}	}	/*	 * now check if it may be flag type argument	 * flag type arguments begin with a '-', a '+' or contain a '='	 * i.e. -flag +flag or flag=	 */	if (argp[0] != '-' && argp[0] != '+' && (!checkeql(argp)))		return (NOTAFLAG);	return (NOTAFILE);}/*---------------------------------------------------------------------------||	compare argp with the format string|	if a match is found store the result a la scanf in one of the|	arguments pointed to in the va_list||	If setargs is FALSE, only check arguments for getfiles()|	in this case, va_list may be a dummy arg.|+---------------------------------------------------------------------------*/LOCAL int doflag(pac, pav, argp, fmt, setargs, oargs)		int		*pac;		char	*const	**pav;	register const char	*argp;	register const char	*fmt;		BOOL		setargs;		va_list		oargs;{	long	val;	int	singlecharflag	= 0;	BOOL	isspec;	BOOL	hasdash		= FALSE;	BOOL	doubledash	= FALSE;	BOOL	haseql		= checkeql(argp);	const char	*sargp;	const char	*sfmt	= fmt;	va_list	args;	char	*const	*spav	= *pav;	int		spac	= *pac;	void		*curarg	= (void *)0;	/*	 * flags beginning with '-' don't have to include the '-' in	 * the format string.	 * flags beginning with '+' have to include it in the format string.	 */	if (argp[0] == '-') {		argp++;		hasdash = TRUE;		/*		 * Implement legacy support for --longopt		 * If we find a double dash, we do not look for combinations		 * of boolean single char flags.		 */		if (argp[0] == '-') {			argp++;			doubledash = TRUE;			/*			 * Allow -- only for long options.			 */			if (argp[1] == '\0') {				return (BADFLAG);			}		}	}	sargp = argp;	/*	 * Initialize 'args' to the start of the argument list.	 * I don't know any portable way to copy an arbitrary	 * C object so I use a system-specific routine	 * (probably a macro) from stdarg.h.  (Remember that	 * if va_list is an array, 'args' will be a pointer	 * and '&args' won't be what I would need for memcpy.)	 * It is a system requirement for SVr4 compatibility	 * to be able to do this assgignement. If your system	 * defines va_list to be an array but does not define	 * va_copy() you are lost.	 * This is needed to make sure, that 'oargs' will not	 * be clobbered.	 */	va_copy(args, oargs);	if (setargs)		curarg = va_arg(args, void *);	/*	 * check if the first flag in format string is a singlechar flag	 */	if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0')		singlecharflag++;	/*	 * check the whole format string for a match	 */	for(;;) {		for(;*fmt; fmt++,argp++) {			if (*fmt == '\\') {				/*				 * Allow "#?*&+" to appear inside a flag.				 * NOTE: they must be escaped by '\\' only				 *	 inside the the format string.				 */				fmt++;				isspec = FALSE;			} else {				isspec = isfmtspec(*fmt);			}			/*			 * If isspec is TRUE, the arg beeing checked starts			 * like a valid flag. Argp now points to the rest.			 */			if (isspec) {				/*				 * If *argp is '+' and we are on the				 * beginning of the arg that is currently				 * checked, this cannot be an inc type flag.				 */				if (*argp == '+' && argp == sargp)					continue;				/*				 * skip over to arg of flag				 */				if (*argp == '=') {					argp++;				} else if (*argp != '\0' && haseql) {					/*					 * Flag and arg are not separated by a					 * space.					 * Check here for:					 * xxxxx=yyyyy	match on '&'					 * Checked before:					 * abc=yyyyy	match on 'abc&'					 * 		or	 'abc*' 					 * 		or	 'abc#' 					 * We come here if 'argp' starts with					 * the same sequence as a valid flag					 * and contains an equal sign.					 * We have tested before if the text					 * before 'argp' matches exactly.					 * At this point we have no exact match					 * and we only allow to match					 * the special pattern '&'.					 * We need this e.g. for 'make'.					 * We allow any flag type argument to					 * match the format string "&" to set					 * up a function that handles all odd					 * stuff that getargs will not grok.					 * In addition, to allow getargs to be

⌨️ 快捷键说明

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