/*====================================================================*
*
* int getoptv (int argc, char const * argv[], char const * optv[]);
*
* getoptv.h
*
* this is a posix compliant getopt() function that supports no
* extensions; see the posix website for specification details;
*
* <http://www.opengroup.org/onlinepubs/007904975/functions/getopt.html>
*
* we implemented this function to ensure that linux and windows
* consoles act the same; microsoft c++ would not compile the
* debian version of getopt and so, after trying to fix things,
* we decided to start fresh; the debian version is too complex;
*
* this function conforms to posix standard; it does not support
* gnu style extensions like "--option" for arguments or "ab::c"
* for operands; if you don't know what that means then you won't
* care, either; you should avoid such extentions, anyway;
*
* the posix standard says that command options and operands must
* precede other arguments; this version of getopt allows options
* and operands to appear anywhere and makes non-compliant argv[]
* compliant in the process;
*
* we define characters instead of coding them so that microsoft
* folks can use '/' instead of '-' and still preserve the posix
* behaviour;
*
* we declare optarg as "char const *" so that the target cannot
* be changed by the application; this is not POSIX compliant so
* it will conflict with other getopt variants; getopt.h is often
* included with unistd.h which is a common file;
*
* systems.
*
* this version calls virtually no functions and should compile
* on any posix system;
*
* you may include getoptv.h or declare these variables:
*
* extern char const *optarg;
* extern int optopt;
* extern int optind;
* extern int opterr;
*
* you may cut and paste this c language code segment to get you
* started; you must insert your own code and case breaks;
*
* signed c;
* optind = 1;
* opterr = 1;
*
* while ((c = getoptv(argc, argv, * optv)) != -1)
* {
* switch(c)
* {
* case 'a': // optopt is 'a'; optarg is NULL;
* case 'b': // optopt is 'b'; optarg is operand;
* case ':': // optopt is option; optarg is NULL; missing operand;
* case '?': // optopt is option; optarg is NULL; illegal option;
* default: // optopt is option: optarg is NULL; illegal option;
* }
* }
*
* after options and operands are processed, optind points to
* the next argv [] string; loop until optind equals argc or
* argv[optind] is NULL; we check both but either will do;
*
* while ((optind < argc) && (argv [optind]))
* {
* // do stuff to argv[optind++].
* }
*
* alternately, and even better, the following works just fine:
*
* argc -= optind;
* argv += optind;
* while ((argc) && (* argv))
* {
* // do stuff to * argv.
*
* }
*
* Motley Tools by Charles Maier <cmaier@cmassoc.net>;
* Copyright (c) 2001-2006 by Charles Maier Associates;
* licensed under the Internet Software Consortium License;
*
*--------------------------------------------------------------------*/
#ifndef GETOPTV_SOURCE
#define GETOPTV_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../tools/getoptv.h"
#include "../tools/putoptv.h"
#include "../tools/version.h"
#include "../tools/error.h"
char const * program_name = "program";
char * optarg = (char *) (0);
signed optopt = (char) (0);
signed optind = 1;
signed opterr = 1;
signed optmin = 0;
signed getoptv (int argc, char const * argv [], char const * optv [])
{
static char const * string;
static char const * option;
static signed count;
signed index;
if ((optind == 0) || (optind == 1))
{
for (program_name = string = * argv; * string; string++)
{
if ((* string == '/') || (* string == '\\'))
{
program_name = string + 1;
}
}
string = (char *) (0);
if (argc == optmin)
{
putoptv (optv);
exit (0);
}
count = optind = 1;
}
while ((count < argc) || (string))
{
if (string)
{
if (*string)
{
optarg = (char *) (0);
optopt = *string++;
for (option = * optv; * option; option++)
{
if (optopt == GETOPTV_C_OPERAND)
{
continue;
}
if (*option == GETOPTV_C_OPERAND)
{
continue;
}
if (*option == optopt)
{
option++;
if (*option != GETOPTV_C_OPERAND)
{
return (optopt);
}
if (*string)
{
optarg = (char *) (string);
string = (char *) (0);
return (optopt);
}
if (count < argc)
{
optarg = (char *)(argv [count]);
for (index = count++; index > optind; index--)
{
argv [index] = argv [index - 1];
}
argv [optind++] = optarg;
return (optopt);
}
if (opterr)
{
error (1, 0, "option '%c' needs an operand.", optopt);
}
if (** optv == GETOPTV_C_OPERAND)
{
return (GETOPTV_C_OPERAND);
}
return (GETOPTV_C_ILLEGAL);
}
}
if (opterr)
{
error (1, 0, "option '%c' has no meaning.", optopt);
}
return (GETOPTV_C_ILLEGAL);
}
else
{
string = (char *) (0);
}
}
if (count < argc)
{
string = argv [count];
if (*string == GETOPTV_C_OPTION)
{
for (index = count; index > optind; index--)
{
argv [index] = argv [index - 1];
}
argv [optind++] = string++;
if (*string == GETOPTV_C_VERSION)
{
version ();
exit (0);
}
if (*string == GETOPTV_C_SUMMARY)
{
putoptv (optv);
exit (0);
}
if (*string == GETOPTV_C_OPTION)
{
string++;
if (!strcmp (string, ""))
{
optarg = (char *) (0);
optopt = (char) (0);
return (-1);
}
if (!strcmp (string, "version"))
{
version ();
exit (0);
}
if (!strcmp (string, "help"))
{
putoptv (optv);
exit (0);
}
optarg = (char *)(string);
optopt = GETOPTV_C_OPTION;
return (-1);
}
}
else
{
string = (char *) (0);
}
count++;
}
}
optarg = (char *) (0);
optopt = (char) (0);
return (-1);
}
#endif