Newer
Older
Microsoft / getopt / GETOPT.C
@tundra tundra on 24 May 2012 4 KB Initial revision
#define MODNAME "getopt"

/*****************************************************************************
**
**		GETOPT -- Function to provide look-alike functionality to the
**					Unix System V getopt(3) function.
**
**	See the Unix System V User's Manual getopt(3) for complete usage
**	details.
**
*****************************************************************************/
#include <stdio.h>
/* #include <string.h> */

typedef	int BOOL;

#define MINUS '-'
#define COLON ':'
#define QUESTION '?'
#define CNULL '\0'
    
    
char *optarg = NULL;
int optind = 0;

getopt(argc,argv,optstring)
int argc;
char **argv;
char *optstring;
{
    static int curarg = 0;
    static int curopt = 0;
	static BOOL done = FALSE;
	static char progname[13];
    char *tptr;
    
	if ((curarg == 0) && (curopt == 0))
		{
		tptr = strrchr(*argv,'\\');
		tptr++;
		tptr = strncpy(progname,tptr,12);
		if ((tptr = strrchr(progname,'.')) != NULL)
			*tptr = CNULL;
		curarg = curopt = 1;
		}
    if (!done && (argv[curarg] != NULL) && (*argv[curarg] == MINUS))
        {
        if ((curopt == 1) && (argv[curarg][curopt] == MINUS))
			{
			curarg++;
			curopt = 1;
			done = TRUE;
			}
        else if ((tptr = strchr(optstring,argv[curarg][curopt])) != NULL)
            {
            curopt++;
            if (*(tptr+1) == COLON)
                {
                if (argv[curarg][curopt] == CNULL)
                    {
                    curarg++;
                    optarg = argv[curarg];
                    curarg++;
                    curopt = 1;
                    }
                else
                    {
                    optarg = &argv[curarg][curopt];
                    curarg++;
                    curopt = 1;
                    }
                }
			else
				{
				if (argv[curarg][curopt] == CNULL)
					{
					curarg++;
					curopt = 1;
					}
				optarg = NULL;
				}
			return((int)*tptr);
			}
		else
			{
			fprintf(stderr,"%s: illegal option -- %c\n",progname,argv[curarg][curopt]);
			curopt++;
			if (argv[curarg][curopt] == CNULL)
				{
				curarg++;
				curopt = 1;
				}
			optarg = NULL;
			return((int)QUESTION);
			}
		}
	else
		done = TRUE;
	
	optind = curarg;
	optarg = NULL;
	return(EOF);
}
                
/*****************************************************************************
**
**	Programming Example: (taken from AT&T's Internal UNIX System Calls
**							class manual, pages 2.1.4 through 2.1.12)
**
***********
**
**	#define MODNAME "test"
**
**	#include <stdio.h>
**	
**	extern char *optarg;
**	extern int optind;
**	
**	main(argc,argv)
**	int argc;
**	char **argv;
**	{
**		int getopt(),c;
**		static char options[] = "adf:g:";
**		int n, invalid = 0, a_ind = 0, d_ind = 0;
**		char *f_ptr = NULL, *g_ptr = NULL;
**	
**		printf("argc contains %d\n",argc);
**		printf("argv contains %0X\n\n",argv);
**	
**		while ((c = getopt(argc,argv,options)) != EOF)
**			switch(c)
**				{
**				case 'a':
**					{
**					a_ind++;
**					break;
**					}
**				case 'd':
**					{
**					d_ind++;
**					break;
**					}
**				case 'f':
**					{
**					f_ptr = optarg;
**					break;
**					}
**				case 'g':
**					{
**					g_ptr = optarg;
**					break;
**					}
**				case '?':
**					invalid++;
**				}
**		printf("argc contains %d\n",argc);
**		printf("argv contains %0X\n",argv);
**		printf("a_ind contains %d\n",a_ind);
**		printf("d_ind contains %d\n",d_ind);
**		printf("f_ptr points to %s\n",f_ptr);
**		printf("g_ptr points to %s\n",g_ptr);
**		printf("invalid contains %d\n",invalid);
**		printf("optind contains %d\n",optind);
**		for (;optind < argc;optind++)
**			printf("next parameter[%d] = %s\n",optind,argv[optind]);
**		return;
**	}
**
***********
**
**	Invoke this example with:
**
**		C>test -abcfabc -g hij -a file1 file2<CR>
**
**	Output:
**
**		argc contains 7
**		argv contains FD0
**	
**		TEST: illegal option -- b
**		TEST: illegal option -- c
**		argc contains 7
**		argv contains FD0
**		a_ind contains 2
**		d_ind contains 0
**		f_ptr points to abc
**		g_ptr points to hij
**		invalid contains 2
**		optind contains 5
**		next parameter[5] = file1
**		next parameter[6] = file2
**
*****************************************************************************/