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

📄 goptions.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************** Start of $RCSfile: goptions.c,v $  ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/goptions.c,v $* $Id: goptions.c,v 1.3 2004/07/08 20:34:44 alb Exp alb $* $Date: 2004/07/08 20:34:44 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h>  static char * fileversion = "$RCSfile: goptions.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/goptions.c,v $ $Id: goptions.c,v 1.3 2004/07/08 20:34:44 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <string.h>#include <stdarg.h>#include <x_types.h>#include <x_errno.h>#include <genutils.h>#include <fileutil.h>#include <ctype.h>#define	GETOUT	{ goto getout; }#define	CLEANUP	{ goto cleanup; }struct optdesc {  Int32		minargs;  Int32		maxargs;  UChar		*optname;  Int32		*argnumptr;  void		**arglist;  UChar		*plusoptptr;  X_Type	argtype;  Flag		plusopt;  Flag		countflag;};#define	newarg	\	{	args = ZRENEWP(args, struct optdesc, num_args + 1); \		if(!args) \		  GETOUT; \		SETZERO(args[num_args]); \		args[num_args].optname = NULL; \		actarg = num_args; \		num_args++; \	}#define	act	optstring[i]#define	errexit(num)	{ errno = r = num ; GETOUT ; }#define	nextc	{ i++; while(isspace(optstring[i]) && optstring[i]) i++; \			if(!optstring[i]) errexit(BAD_STRING_FORMAT); }#define	NOT_USED	-1#define	OPTION_FLAGS	-2#define	TypeUNUSED_ARG	TypeReal32PTRstatic Int32	all_flag_args(UChar *, struct optdesc *, Int32);Int32goptions(  Int32		argc,  UChar		**argv,  UChar		*optionstring,  ...){  va_list       	add_args;  struct optdesc	*args = NULL;  Int32			num_args = 0, actarg, used_args, idx;  Int32			nonames, i, j, argoffset = 0, ii;  Int32			unused_args_idx = -1;  UChar			*cptr;  Int32			*argtable = NULL, r = NO_ERROR;  UChar			**argstrings = NULL, *optstring = NULL;  UChar			no_msgs = 0;  int			n;  long int		ibuf;  if(argc < 0){    argc = -argc;    no_msgs = 1;  }			    /* get memory for some stuff and initialize it */  argstrings = NEWP(UChar *, argc + argc);	 /* 2*argc is safety space */  argtable = NEWP(Int32, argc);  optstring = strdup(optionstring);	    /* work on duplicate, cause it */  if(!argstrings || !argtable || !optstring)	      /* is to be modified */    errexit(errno);  for(i = 0; i < argc; i++){    argtable[i] = NOT_USED;  }	      /* build a record of possible options from the option-string */  i = 0;	 /* i points to the current character in the option-string */  forever{    while(act == ';')				      /* skip separator(s) */	i++;    if(!act)			/* act is defined as the current character */	break;    newarg;		 /* increment i, skip whitespace and check for EOS */    if(act == '+'){			       /* option starts with a '+' */	args[actarg].plusopt = 1;	nextc;    }    switch(act){			/* select format character -> type */	case 'f':		args[actarg].argtype = TypeReal32;		break;	case 'd':		args[actarg].argtype = TypeReal64;		break;	case 'i':		args[actarg].argtype = TypeInt32;		break;	case 'u':		args[actarg].argtype = TypeUns32;		break;	case 'b':		args[actarg].argtype = TypeUChar;		break;	case 'c':		args[actarg].argtype = TypeInt32;		args[actarg].countflag = YES;		break;	case 's':		args[actarg].argtype = TypeUCharPTR;		break;	case '*':		args[actarg].argtype = TypeUNUSED_ARG;		break;	default:		errexit(BAD_STRING_FORMAT);    }    if(args[actarg].argtype != TypeUNUSED_ARG)	nextc;    if(args[actarg].argtype == TypeUNUSED_ARG){	args[actarg].minargs = 2;	args[actarg].maxargs = 2;	unused_args_idx = actarg;    }    else if(act == ':'){		     /* separator ? -> no range of */	args[actarg].minargs = 1;	       /* option arguments defined */	args[actarg].maxargs = 1;	       /* -> 1 argument for option */    }    else{	if(args[actarg].argtype == TypeUChar)	  errexit(BAD_STRING_FORMAT);	if(act == '-'){					  /* opening range */	  args[actarg].minargs = 0;		  /* get maximum # of args */	  nextc;	  if(1 > sscanf(optstring + i, "%ld%n", &ibuf, &n))	    errexit(BAD_STRING_FORMAT);	  args[actarg].maxargs = ibuf;	  if(args[actarg].maxargs < 0)	     /* illegal value: maximum < 0 */	    errexit(ILLEGAL_VALUE);	  i += n - 1;	  nextc;	}	else{					       /* get first number */	  if(1 > sscanf(optstring + i, "%ld%n", &ibuf, &n))	    errexit(BAD_STRING_FORMAT);	  args[actarg].minargs = ibuf;	  i += n - 1;	  nextc;	  if(act == '-'){		 /* range given: get second number */	    nextc;	    if(1 > sscanf(optstring + i, "%ld%n", &ibuf, &n))	      errexit(BAD_STRING_FORMAT);	    args[actarg].maxargs = ibuf;	    i += n - 1;	    nextc;	    if(act != ':')		  /* syntax check, ':' must follow */	      errexit(BAD_STRING_FORMAT);						 /* exchange, if min > max */	    if(args[actarg].maxargs < args[actarg].minargs)		memswap(&args[actarg].maxargs, &args[actarg].minargs,							sizeof(Int32));	    if(args[actarg].minargs < 0 || args[actarg].maxargs < 0)		errexit(ILLEGAL_VALUE);	 /* illegal values: min || max < 0 */	  }	  else		      /* no range: exact number of arguments given */	    args[actarg].maxargs = args[actarg].minargs;	}	if(act != ':')			  /* syntax check, ':' must follow */	  errexit(BAD_STRING_FORMAT);    }    i++;						/* skip whitespace */    while(optstring[i] && isspace(optstring[i]))	i++;    cptr = strchr(optstring + i, ';');		/* find end of option name */    if(cptr)	*cptr = '\0';    if(args[actarg].argtype != TypeUNUSED_ARG)	args[actarg].optname = strdup(optstring + i);	/* get option name */    else	args[actarg].optname = strdup(" ");			/* check for multiple appearance of option names */    for(j = 0; j < num_args - 1; j++){	if(!strcmp(args[j].optname, args[actarg].optname)){	  if(!args[j].optname[0] && ((args[j].argtype == TypeUChar				&& args[actarg].argtype != TypeUChar) ||			(args[j].argtype != TypeUChar				&& args[actarg].argtype == TypeUChar)))	    continue;	/* This is the exception: The empty name may */			/* appear two times: as a boolean option and */							/* one other */	  errexit(MULTIPLE_USE_ILLEGAL);	}    }    if(cptr){	i = cptr - optstring;		/* restore end of option name, */	*cptr = ';';		/* if not at the end of the optionstring */    }    else	i = strlen(optstring);	/* now we're done with the optionstring */  }  for(i = 0; i < num_args; i++){	/* get memory for the pointers */    j = args[i].maxargs;			/* to the arguments */    if(j < 1)				/* for safety we always use >= 1 */	j = 1;    args[i].arglist = NEWP(void *, j);	/* they can be of several types */    if(!args[i].arglist)	errexit(errno);  }  va_start(add_args, optionstring);	/* collect the argument pointers */  for(i = 0; i < num_args; i++){	/* first, if we have a '+'-option */    if(args[i].plusopt && args[i].argtype != TypeUChar)	args[i].plusoptptr = va_arg(add_args, UChar *);    if(args[i].minargs != args[i].maxargs){	/* for the # of arguments */	args[i].argnumptr = va_arg(add_args, Int32 *);    }    for(j = 0; j < args[i].maxargs; j++)	  /* now for the arguments */	args[i].arglist[j] = va_arg(add_args, void *);  }  va_end(add_args);		       /* users arg-pointers are processed */  for(i = 1; i < argc; i++){	      /* step through the command line and */    switch(argv[i][0]){	      /* connect the argv with the options' record */      case '-':			    /* an option always starts with - or + */      case '+':		 /* 1st: the options with names longer than 1 char */	for(j = 0; j < num_args; j++){	  if(((args[j].argtype != TypeUChar && !args[j].countflag)		|| strlen(args[j].optname) > 1) && strlen(argv[i]) > 1/*2*/){	    if(!strncmp(argv[i] + 1, args[j].optname,						strlen(argv[i] + 1))){		if(strlen(argv[i]) == 2){		  for(ii = 0; ii < num_args; ii++){		    if(strlen(args[ii].optname) == 1 && ii != j				&& args[ii].optname[0] == argv[i][1])		      break;		  }		  if(ii < num_args){			if(! no_msgs)			  fprintf(stderr, T_("Warning: one-letter flag %s ambigous, ignored.\n"), argv[i] + 1); 			break;		 /* the name has already been used */		  }		}		if(argtable[i] >= 0){		  if(! no_msgs)		    fprintf(stderr, T_("Warning: Ambigous argument: %s. Second occurrence ignored.\n"), argv[i] + 1); 		  break;		 /* the name has already been used */		}		argtable[i] = j;	   /* mark the index to the record */		if(args[j].argnumptr)		  *args[j].argnumptr = 0;		    /* reset the # */		break;	    }	  }	}	if(j >= num_args){	 /* 2nd: the non-bool options, 1 char leng */	  for(j = 0; j < num_args; j++){	    if(args[j].argtype != TypeUChar && !args[j].countflag					&& strlen(args[j].optname) == 1){		if(argv[i][1] == args[j].optname[0]){		  if(argtable[i] >= 0){		    if(! no_msgs)		      fprintf(stderr, T_("Warning: Ambigous argument: %s. Second occurrence ignored.\n"), argv[i] + 1); 		    break;		 /* the name has already been used */		  }		  argtable[i] = j;	   /* mark the index to the record */		  if(args[j].argnumptr)		    *args[j].argnumptr = 0;		    /* reset the # */		  break;		}	    }	  }	}		   /* 3rd: the options - and + without any letters */	if(j >= num_args && argv[i][1] == '\0'){	  for(j = 0; j < num_args; j++){	    if(! args[j].optname[0] && args[j].argtype == TypeUChar){		argtable[i] = j;

⌨️ 快捷键说明

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