Initial revision.
This commit is contained in:
parent
913fe75558
commit
dfbbb98ed6
2 changed files with 497 additions and 0 deletions
365
Main/fg_getopt.c
Normal file
365
Main/fg_getopt.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/****************************************************************************
|
||||
* Modified from the original version found in SciTech's library. Note that
|
||||
* this in fact may have been copied/derived from a much earlier work as I
|
||||
* remember seeing a version of it 10 years ago for use in CP/M and it wasn't
|
||||
* new then. I peeled a routine out of the end of this as it was an alternative
|
||||
* for Windows code. CH
|
||||
*
|
||||
* Copyright (C) 1991-1997 SciTech Software, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ======================================================================
|
||||
* This library is free software; you can use it and/or
|
||||
* modify it under the terms of the SciTech MGL Software License.
|
||||
*
|
||||
* This library 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
|
||||
* SciTech MGL Software License for more details.
|
||||
* ======================================================================
|
||||
*
|
||||
* Filename: $Workfile: getopt.c $
|
||||
* Version: $Revision$
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: any
|
||||
*
|
||||
* Description: This module contains code to parse the command line,
|
||||
* extracting options and parameters in standard System V
|
||||
* style.
|
||||
*
|
||||
* $Date$ $Author$
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "fg_getopt.h"
|
||||
|
||||
/*------------------------- Global variables ------------------------------*/
|
||||
|
||||
int nextargv = 1; /* Index into argv array */
|
||||
char *nextchar = NULL; /* Pointer to next character */
|
||||
|
||||
/*-------------------------- Implementation -------------------------------*/
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define IS_SWITCH_CHAR(c) (c == '-') || (c == '/')
|
||||
#define IS_NOT_SWITCH_CHAR(c) (c != '-') && (c != '/')
|
||||
#else
|
||||
#define IS_SWITCH_CHAR(c) (c == '-')
|
||||
#define IS_NOT_SWITCH_CHAR(c) (c != '-')
|
||||
#endif
|
||||
|
||||
int getopt(int argc,char **argv,char *format,char **argument)
|
||||
/****************************************************************************
|
||||
*
|
||||
* Function: getopt
|
||||
* Parameters: argc - Value passed to program through argc
|
||||
* variable in the function main.
|
||||
* argv - Pointer to the argv array that is passed to
|
||||
* the program in function main.
|
||||
* format - A string representing the expected format
|
||||
* of the command line options that need to be
|
||||
* parsed.
|
||||
* argument - Pointer to optional argument on command
|
||||
* line.
|
||||
*
|
||||
* Returns: Character code representing the next option parsed from the
|
||||
* command line by getopt. Returns ALLDONE (-1) when there are
|
||||
* no more parameters to be parsed on the command line,
|
||||
* PARAMETER (-2) when the argument being parsed is a
|
||||
* parameter and not an option switch and lastly INVALID (-3)
|
||||
* if an error occured while parsing the command line.
|
||||
*
|
||||
* Description: Function to parse the command line option switches in
|
||||
* UNIX System V style. When getopt is called, it returns the
|
||||
* character code of the next valid option that is parsed from
|
||||
* the command line as specified by the Format string. The
|
||||
* format string should be in the following form:
|
||||
*
|
||||
* "abcd:e:f:"
|
||||
*
|
||||
* where a,b and c represent single switch style options and
|
||||
* the character code returned by getopt is the only value
|
||||
* returned. Also d, e and f represent options that expect
|
||||
* arguments immediately after them on the command line. The
|
||||
* argument that follows the option on the command line is
|
||||
* returned via a reference in the pointer argument. Thus
|
||||
* a valid command line for this format string might be:
|
||||
*
|
||||
* myprogram -adlines /b /f format infile outfile
|
||||
*
|
||||
* where a and b will be returned as single character options
|
||||
* with no argument, while d is returned with the argument
|
||||
* lines and f is returned with the argument format. Note that
|
||||
* either UNIX style or MS-DOS command switches may be used
|
||||
* interchangeably under MSDOS, but under UNIX only the UNIX
|
||||
* style switches are supported.
|
||||
*
|
||||
* When getopt returns with PARAMETER (we attempted to parse
|
||||
* a paramter, not an option), the global variable NextArgv
|
||||
* will hold an index in the argv array to the argument on the
|
||||
* command line AFTER the options, ie in the above example the
|
||||
* string 'infile'. If the parameter is successfully used,
|
||||
* NextArgv should be incremented and getopt can be called
|
||||
* again to parse any more options. Thus you can also have
|
||||
* options interspersed throught the command line. eg:
|
||||
*
|
||||
* myprogram -adlines infile /b outfile /f format
|
||||
*
|
||||
* can be made to be a valid form of the above command line.
|
||||
*
|
||||
****************************************************************************/
|
||||
{
|
||||
char ch;
|
||||
char *formatchar;
|
||||
|
||||
if (argc > nextargv) {
|
||||
if (nextchar == NULL) {
|
||||
nextchar = argv[nextargv]; /* Index next argument */
|
||||
if(nextchar == NULL) {
|
||||
nextargv++;
|
||||
return ALLDONE; /* No more options */
|
||||
}
|
||||
if(IS_NOT_SWITCH_CHAR(*nextchar)) {
|
||||
nextchar = NULL;
|
||||
return PARAMETER; /* We have a parameter */
|
||||
}
|
||||
nextchar++; /* Move past switch operator */
|
||||
if(IS_SWITCH_CHAR(*nextchar)) {
|
||||
nextchar = NULL;
|
||||
return INVALID; /* Ignore rest of line */
|
||||
}
|
||||
}
|
||||
|
||||
if ((ch = *(nextchar++)) == 0) {
|
||||
nextchar = NULL;
|
||||
return INVALID; /* No options on line */
|
||||
}
|
||||
|
||||
if (ch == ':' || (formatchar = strchr(format, ch)) == NULL)
|
||||
return INVALID;
|
||||
|
||||
if (*(++formatchar) == ':') { /* Expect an argument after option */
|
||||
nextargv++;
|
||||
if (*nextchar == 0) {
|
||||
if (argc <= nextargv)
|
||||
return INVALID;
|
||||
nextchar = argv[nextargv++];
|
||||
}
|
||||
*argument = nextchar;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else { /* We have a switch style option */
|
||||
if (*nextchar == 0) {
|
||||
nextargv++;
|
||||
nextchar = NULL;
|
||||
}
|
||||
*argument = NULL;
|
||||
}
|
||||
return ch; /* return the option specifier */
|
||||
}
|
||||
nextchar = NULL;
|
||||
nextargv++;
|
||||
return ALLDONE; /* no arguments on command line */
|
||||
}
|
||||
|
||||
static int parse_option(Option *optarr, char *argument)
|
||||
/****************************************************************************
|
||||
*
|
||||
* Function: parse_option
|
||||
* Parameters: optarr - Description for the option we are parsing
|
||||
* argument - String to parse
|
||||
* Returns: INVALID on error, ALLDONE on success.
|
||||
*
|
||||
* Description: Parses the argument string depending on the type of argument
|
||||
* that is expected, filling in the argument for that option.
|
||||
* Note that to parse a string, we simply return a pointer
|
||||
* to argument.
|
||||
*
|
||||
****************************************************************************/
|
||||
{
|
||||
int num_read = 0;
|
||||
|
||||
switch ((int)(optarr->type)) {
|
||||
case OPT_INTEGER:
|
||||
num_read = sscanf(argument,"%d",(int*)optarr->arg);
|
||||
break;
|
||||
case OPT_HEX:
|
||||
num_read = sscanf(argument,"%x",(int*)optarr->arg);
|
||||
break;
|
||||
case OPT_OCTAL:
|
||||
num_read = sscanf(argument,"%o",(int*)optarr->arg);
|
||||
break;
|
||||
case OPT_UNSIGNED:
|
||||
num_read = sscanf(argument,"%u",(uint*)optarr->arg);
|
||||
break;
|
||||
case OPT_LINTEGER:
|
||||
num_read = sscanf(argument,"%ld",(long*)optarr->arg);
|
||||
break;
|
||||
case OPT_LHEX:
|
||||
num_read = sscanf(argument,"%lx",(long*)optarr->arg);
|
||||
break;
|
||||
case OPT_LOCTAL:
|
||||
num_read = sscanf(argument,"%lo",(long*)optarr->arg);
|
||||
break;
|
||||
case OPT_LUNSIGNED:
|
||||
num_read = sscanf(argument,"%lu",(ulong*)optarr->arg);
|
||||
break;
|
||||
case OPT_FLOAT:
|
||||
num_read = sscanf(argument,"%f",(float*)optarr->arg);
|
||||
break;
|
||||
case OPT_DOUBLE:
|
||||
num_read = sscanf(argument,"%lf",(double*)optarr->arg);
|
||||
break;
|
||||
case OPT_LDOUBLE:
|
||||
num_read = sscanf(argument,"%Lf",(long double*)optarr->arg);
|
||||
break;
|
||||
case OPT_STRING:
|
||||
num_read = 1; /* This always works */
|
||||
*((char**)optarr->arg) = argument;
|
||||
break;
|
||||
default:
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (num_read == 0)
|
||||
return INVALID;
|
||||
else
|
||||
return ALLDONE;
|
||||
}
|
||||
|
||||
int getargs( int argc,char
|
||||
*argv[],
|
||||
int num_opt,
|
||||
Option **optarr,
|
||||
int (*do_param)(char *param,int num))
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Function: getargs
|
||||
* Parameters: argc - Number of arguments on command line
|
||||
* argv - Array of command line arguments
|
||||
* num_opt - Number of options in option array
|
||||
* optarr - Array to specify how to parse the command line
|
||||
* do_param - Routine to handle a command line parameter
|
||||
* Returns: ALLDONE, INVALID or HELP
|
||||
*
|
||||
* Description: Function to parse the command line according to a table of
|
||||
* options. This routine calls getopt above to parse each
|
||||
* individual option and attempts to parse each option into
|
||||
* a variable of the specified type. The routine can parse
|
||||
* integers and long integers in either decimal, octal,
|
||||
* hexadecimal notation, unsigned integers and unsigned longs,
|
||||
* strings and option switches. Option switches are simply
|
||||
* boolean variables that get turned on if the switch was
|
||||
* parsed.
|
||||
*
|
||||
* Parameters are extracted from the command line by calling
|
||||
* a user supplied routine do_param() to handle each parameter
|
||||
* as it is encountered. The routine do_param() should accept
|
||||
* a pointer to the parameter on the command line and an
|
||||
* integer representing how many parameters have been
|
||||
* encountered (ie: 1 if this is the first parameter, 10 if
|
||||
* it is the 10th etc), and return ALLDONE upon successfully
|
||||
* parsing it or INVALID if the parameter was invalid.
|
||||
*
|
||||
* We return either ALLDONE if all the options were
|
||||
* successfully parsed, INVALID if an invalid option was
|
||||
* encountered or HELP if any of -h, -H or -? were present
|
||||
* on the command line.
|
||||
*
|
||||
****************************************************************************/
|
||||
{
|
||||
int i,opt;
|
||||
char *argument;
|
||||
int param_num = 1;
|
||||
char cmdstr[MAXARG*2 + 4];
|
||||
|
||||
/* Build the command string from the array of options */
|
||||
|
||||
strcpy(cmdstr,"hH?");
|
||||
for (i = 0,opt = 3; i < num_opt; i++,opt++) {
|
||||
cmdstr[opt] = optarr[i]->opt;
|
||||
if (optarr[i]->type != OPT_SWITCH) {
|
||||
cmdstr[++opt] = ':';
|
||||
}
|
||||
}
|
||||
cmdstr[opt] = '\0';
|
||||
|
||||
while (true) {
|
||||
opt = getopt(argc,argv,cmdstr,&argument);
|
||||
switch (opt) {
|
||||
case 'H':
|
||||
case 'h':
|
||||
case '?':
|
||||
return HELP;
|
||||
case ALLDONE:
|
||||
return ALLDONE;
|
||||
case INVALID:
|
||||
return INVALID;
|
||||
case PARAMETER:
|
||||
if (do_param == NULL)
|
||||
return INVALID;
|
||||
if (do_param(argv[nextargv],param_num) == INVALID)
|
||||
return INVALID;
|
||||
nextargv++;
|
||||
param_num++;
|
||||
break;
|
||||
default:
|
||||
|
||||
/* Search for the option in the option array. We are
|
||||
* guaranteed to find it.
|
||||
*/
|
||||
|
||||
for (i = 0; i < num_opt; i++) {
|
||||
if (optarr[i]->opt == opt)
|
||||
break;
|
||||
}
|
||||
if (optarr[i]->type == OPT_SWITCH)
|
||||
*((bool*)optarr[i]->arg) = true;
|
||||
else {
|
||||
if (parse_option( optarr[i],argument) == INVALID)
|
||||
return INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_desc(int num_opt,Option **optarr)
|
||||
/****************************************************************************
|
||||
*
|
||||
* Function: print_desc
|
||||
* Parameters: num_opt - Number of options in the table
|
||||
* optarr - Table of option descriptions
|
||||
*
|
||||
* Description: Prints the description of each option in a standard format
|
||||
* to the standard output device. The description for each
|
||||
* option is obtained from the table of options.
|
||||
*
|
||||
****************************************************************************/
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_opt; i++) {
|
||||
if (optarr[i]->type == OPT_SWITCH)
|
||||
printf(" -%c %s\n",optarr[i]->opt,optarr[i]->desc);
|
||||
else
|
||||
printf(" -%c<arg> %s\n",optarr[i]->opt,optarr[i]->desc);
|
||||
}
|
||||
}
|
||||
|
||||
// End of getopt.c
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.1 1998/02/13 00:23:40 curt
|
||||
/* Initial revision.
|
||||
/*
|
||||
*/
|
132
Main/fg_getopt.h
Normal file
132
Main/fg_getopt.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 1991-1997 SciTech Software, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ======================================================================
|
||||
* This library is free software; you can use it and/or
|
||||
* modify it under the terms of the SciTech MGL Software License.
|
||||
*
|
||||
* This library 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
|
||||
* SciTech MGL Software License for more details.
|
||||
* ======================================================================
|
||||
*
|
||||
* Filename: $Workfile: getopt.h $
|
||||
* Version: $Revision$
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: any
|
||||
*
|
||||
* Description: Header file for command line parsing module. This module
|
||||
* contains code to parse the command line, extracting options
|
||||
* and parameters in standard System V style.
|
||||
*
|
||||
* $Date$ $Author$
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __GETOPT_H
|
||||
#define __GETOPT_H
|
||||
|
||||
//#ifndef __DEBUG_H
|
||||
//#include "debug.h"
|
||||
//#endif
|
||||
|
||||
/*---------------------------- Typedef's etc -----------------------------*/
|
||||
|
||||
#define ALLDONE -1
|
||||
#define PARAMETER -2
|
||||
#define INVALID -3
|
||||
#define HELP -4
|
||||
|
||||
#define MAXARG 80
|
||||
|
||||
/* Option type sepecifiers */
|
||||
|
||||
#define OPT_INTEGER 'd'
|
||||
#define OPT_HEX 'h'
|
||||
#define OPT_OCTAL 'o'
|
||||
#define OPT_UNSIGNED 'u'
|
||||
#define OPT_LINTEGER 'D'
|
||||
#define OPT_LHEX 'H'
|
||||
#define OPT_LOCTAL 'O'
|
||||
#define OPT_LUNSIGNED 'U'
|
||||
#define OPT_FLOAT 'f'
|
||||
#define OPT_DOUBLE 'F'
|
||||
#define OPT_LDOUBLE 'L'
|
||||
#define OPT_STRING 's'
|
||||
#define OPT_SWITCH '!'
|
||||
|
||||
// I need to generate a typedefs file for this.
|
||||
//
|
||||
#ifndef uchar
|
||||
typedef unsigned char uchar;
|
||||
#endif
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
#ifndef ulong
|
||||
typedef unsigned long ulong;
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#ifndef BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
typedef BOOL bool;
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#define true TRUE
|
||||
#define false FALSE
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uchar opt; /* The letter to describe the option */
|
||||
uchar type; /* Type descriptor for the option */
|
||||
void *arg; /* Place to store the argument */
|
||||
char *desc; /* Description for this option */
|
||||
} Option;
|
||||
|
||||
#define NUM_OPT(a) sizeof(a) / sizeof(Option)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*--------------------------- Global variables ---------------------------*/
|
||||
|
||||
extern int nextargv;
|
||||
extern char *nextchar;
|
||||
|
||||
/*------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
// extern int getopt(int argc,char **argv,char *format,char **argument);
|
||||
|
||||
extern int getargs(int argc, char *argv[],int num_opt, Option ** optarr,
|
||||
int (*do_param)(char *param,int num));
|
||||
|
||||
extern void print_desc(int num_opt, Option **optarr); // Not original code
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.1 1998/02/13 00:23:39 curt
|
||||
/* Initial revision.
|
||||
/*
|
||||
*/
|
Loading…
Add table
Reference in a new issue