Added parseOptions to add getopt() functionality (and allow compiling on WIN32)

This commit is contained in:
Ralph Lange
2004-01-20 12:41:16 +00:00
parent f58b4e2efd
commit 3ea334068e
5 changed files with 180 additions and 40 deletions

View File

@@ -18,7 +18,7 @@ SHARED_LIBRARIES = NO
LIBRARY_HOST += catools
catools_SRCS += tool_lib.c
catools_SRCS += tool_lib.c parseOptions.c
catools_LIBS += ca Com
#Remove LIBNAME from the library names to be installed (make it a local library)

View File

@@ -21,15 +21,12 @@
#include <string.h>
#include <malloc.h>
#if defined(_WIN32)
#include <getopt.h>
#endif
#include <alarm.h>
#include <tsDefs.h>
#include <cadef.h>
#include "tool_lib.h"
#include "parseOptions.h"
#define VALID_DOUBLE_DIGITS 18 /* Max usable precision for a double */
#define PEND_EVENT_SLICES 5 /* No. of pend_event slices for callback requests */
@@ -58,17 +55,17 @@ void usage (void)
" -n: Print DBF_ENUM values as number (default are enum string values)\n"
" -d <type>: Request specific dbr type; use string (DBR_ prefix may be omitted)\n"
" or number of one of the following types:\n"
" DBR_STRING 0 DBR_STS_FLOAT 9 DBR_TIME_LONG 19 DBR_CTRL_SHORT 29\n"
" DBR_INT 1 DBR_STS_ENUM 10 DBR_TIME_DOUBLE 20 DBR_CTRL_INT 29\n"
" DBR_SHORT 1 DBR_STS_CHAR 11 DBR_GR_STRING 21 DBR_CTRL_FLOAT 30\n"
" DBR_FLOAT 2 DBR_STS_LONG 12 DBR_GR_SHORT 22 DBR_CTRL_ENUM 31\n"
" DBR_ENUM 3 DBR_STS_DOUBLE 13 DBR_GR_INT 22 DBR_CTRL_CHAR 32\n"
" DBR_CHAR 4 DBR_TIME_STRING 14 DBR_GR_FLOAT 23 DBR_CTRL_LONG 33\n"
" DBR_LONG 5 DBR_TIME_INT 15 DBR_GR_ENUM 24 DBR_CTRL_DOUBLE 34\n"
" DBR_DOUBLE 6 DBR_TIME_SHORT 15 DBR_GR_CHAR 25 DBR_STSACK_STRING 37\n"
" DBR_STS_STRING 7 DBR_TIME_FLOAT 16 DBR_GR_LONG 26 DBR_CLASS_NAME 38\n"
" DBR_STS_SHORT 8 DBR_TIME_ENUM 17 DBR_GR_DOUBLE 27\n"
" DBR_STS_INT 8 DBR_TIME_CHAR 18 DBR_CTRL_STRING 28\n"
" DBR_STRING 0 DBR_STS_FLOAT 9 DBR_TIME_LONG 19 DBR_CTRL_SHORT 29\n"
" DBR_INT 1 DBR_STS_ENUM 10 DBR_TIME_DOUBLE 20 DBR_CTRL_INT 29\n"
" DBR_SHORT 1 DBR_STS_CHAR 11 DBR_GR_STRING 21 DBR_CTRL_FLOAT 30\n"
" DBR_FLOAT 2 DBR_STS_LONG 12 DBR_GR_SHORT 22 DBR_CTRL_ENUM 31\n"
" DBR_ENUM 3 DBR_STS_DOUBLE 13 DBR_GR_INT 22 DBR_CTRL_CHAR 32\n"
" DBR_CHAR 4 DBR_TIME_STRING 14 DBR_GR_FLOAT 23 DBR_CTRL_LONG 33\n"
" DBR_LONG 5 DBR_TIME_INT 15 DBR_GR_ENUM 24 DBR_CTRL_DOUBLE 34\n"
" DBR_DOUBLE 6 DBR_TIME_SHORT 15 DBR_GR_CHAR 25 DBR_STSACK_STRING 37\n"
" DBR_STS_STRING 7 DBR_TIME_FLOAT 16 DBR_GR_LONG 26 DBR_CLASS_NAME 38\n"
" DBR_STS_SHORT 8 DBR_TIME_ENUM 17 DBR_GR_DOUBLE 27\n"
" DBR_STS_INT 8 DBR_TIME_CHAR 18 DBR_CTRL_STRING 28\n"
"Arrays: Value format: print number of requested values, then list of values\n"
" Default: Print all values\n"
" -# <count>: Print first <count> elements of an array\n"
@@ -137,7 +134,8 @@ void event_handler (evargs args)
int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
chtype dbrType, unsigned long reqElems)
{
int i, n, result;
unsigned int i;
int n, result;
for (n = 0; n < nPvs; n++) {
@@ -322,7 +320,7 @@ int main (int argc, char *argv[])
setvbuf(stdout,NULL,_IOLBF,0); /* Set stdout to line buffering */
while ((opt = getopt(argc, argv, ":taicnhe:f:#:d:0:w:")) != -1) {
while ((opt = parseOptions(argc, argv, ":taicnhe:f:#:d:0:w:")) != -1) {
switch (opt) {
case 'h': /* Print usage */
usage();
@@ -339,13 +337,13 @@ int main (int argc, char *argv[])
case 'd': /* Data type specification */
complainIfNotPlainAndSet(&format, specifiedDbr);
/* Argument (type) may be text or number */
if (sscanf(optarg, "%d", &type) != 1)
if (sscanf(optArgument, "%d", &type) != 1)
{
dbr_text_to_type(optarg, type);
dbr_text_to_type(optArgument, type);
if (type == -1) /* Invalid? Try prefix DBR_ */
{
char str[30] = "DBR_";
strncat(str, optarg, 25);
strncat(str, optArgument, 25);
dbr_text_to_type(str, type);
}
}
@@ -361,26 +359,26 @@ int main (int argc, char *argv[])
charAsNr=1;
break;
case 'w': /* Set CA timeout value */
if(sscanf(optarg,"%lf", &timeout) != 1)
if(sscanf(optArgument,"%lf", &timeout) != 1)
{
fprintf(stderr, "'%s' is not a valid timeout value "
"- ignored. ('caget -h' for help.)\n", optarg);
"- ignored. ('caget -h' for help.)\n", optArgument);
timeout = DEFAULT_TIMEOUT;
}
break;
case '#': /* Array count */
if (sscanf(optarg,"%d", &count) != 1)
if (sscanf(optArgument,"%d", &count) != 1)
{
fprintf(stderr, "'%s' is not a valid array element count "
"- ignored. ('caget -h' for help.)\n", optarg);
"- ignored. ('caget -h' for help.)\n", optArgument);
count = 0;
}
break;
case 'e': /* Select %e format, using <arg> digits */
if (sscanf(optarg, "%d", &digits) != 1)
if (sscanf(optArgument, "%d", &digits) != 1)
fprintf(stderr,
"Invalid precision argument '%s' "
"for option '-e' - ignored.\n", optarg);
"for option '-e' - ignored.\n", optArgument);
else
{
if (digits>=0 && digits<=VALID_DOUBLE_DIGITS)
@@ -391,9 +389,9 @@ int main (int argc, char *argv[])
}
break;
case 'f': /* Select %f format, using <arg> digits */
if (sscanf(optarg, "%d", &digits) != 1)
if (sscanf(optArgument, "%d", &digits) != 1)
fprintf(stderr, "Invalid precision argument '%s' "
"for option '-f' - ignored.\n", optarg);
"for option '-f' - ignored.\n", optArgument);
else
{
if (digits>=0 && digits<=VALID_DOUBLE_DIGITS)
@@ -405,24 +403,24 @@ int main (int argc, char *argv[])
break;
case '0': /* Select integer format */
type = DBR_LONG;
switch ((char) *optarg) {
switch ((char) *optArgument) {
case 'x': outType = hex; break; /* 0x print Hex */
case 'b': outType = bin; break; /* 0b print Binary */
case 'o': outType = oct; break; /* 0o print Octal */
default :
fprintf(stderr, "Invalid argument '%s' "
"for option '-0' - ignored.\n", optarg);
"for option '-0' - ignored.\n", optArgument);
}
break;
case '?':
fprintf(stderr,
"Unrecognized option: '-%c'. ('caget -h' for help.)\n",
optopt);
optChar);
return 1;
case ':':
fprintf(stderr,
"Option '-%c' requires an argument. ('caget -h' for help.)\n",
optopt);
optChar);
return 1;
default :
usage();
@@ -430,7 +428,7 @@ int main (int argc, char *argv[])
}
}
nPvs = argc - optind; /* Remaining arg list are PV names */
nPvs = argc - optIndex; /* Remaining arg list are PV names */
if (nPvs < 1)
{
@@ -455,8 +453,8 @@ int main (int argc, char *argv[])
}
/* Connect channels */
for (n = 0; optind < argc; n++, optind++)
pvs[n].name = argv[optind]; /* Copy PV names from command line */
for (n = 0; optIndex < argc; n++, optIndex++)
pvs[n].name = argv[optIndex]; /* Copy PV names from command line */
connect_pvs(pvs, nPvs);

View File

@@ -0,0 +1,88 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
* Synchrotronstrahlung.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Id$
*
* Author: Ralph Lange (BESSY)
*
*/
#include <string.h>
#include "parseOptions.h"
int optIndex = 1;
char *optArgument = NULL;
char optChar;
static unsigned int charIndex;
int parseOptions (int argc, char * const argv[], const char *options)
{
unsigned int i;
char *opt = argv[optIndex];
if (charIndex >= strlen(opt)) /* End of option group */
{
charIndex = 0;
optIndex++;
}
if (charIndex == 0) /* Search for next option group */
{
for (; optIndex < argc; optIndex++)
{
if (*(opt = argv[optIndex]) == '-')
{
if (*(opt+1) != '-')
{ /* New option group found */
charIndex++;
break;
}
optIndex++;
}
/* No more options */
return -1;
}
if (charIndex == 0) return -1; /* No more options */
}
optChar = opt[charIndex]; /* Test candidate */
for (i = 0; i < strlen(options); i++) /* Check for validity */
{
if (optChar == options[i]) /* Found option in option string! */
{
if (options[i+1] == ':') /* Option has an argument? */
{ /* Set optArgument accordingly */
optIndex++; /* Point to next argument */
if (charIndex+1 >= strlen(opt))
{ /* End of option group */
optArgument = argv[optIndex];
charIndex = 0;
if (*optArgument == '-')
return options[0] == ':' ? ':' : '?';
optIndex++;
} else { /* point to remaining argument */
optArgument = opt + charIndex+1;
}
charIndex = 0;
} else {
optArgument = 0;
charIndex++;
}
return optChar;
}
}
/* Option not found */
charIndex++;
return '?';
}

View File

@@ -0,0 +1,58 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
* Synchrotronstrahlung.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Id$
*
* Author: Ralph Lange (BESSY)
*
*/
#ifndef INCLparseOptionsh
#define INCLparseOptionsh
/* This is a minimal version of a parser whose function is somewhat getopt()
* compatible. Subsequent calls return the command line options one by one.
* The special option "--" forces the end of option scanning.
*
* parseOptions returns the option character found on the command line
* returns '?' if an option is invalid / misses an argument (see below)
* returns -1 if there are no more options (argv[optIndex] is
* the first non-option argument)
*
* options - valid options string (format is similar to getopt):
* <letter> for a valid option
* <letter>: for an option that takes an argument
* : as first character: parseOptions will return ':'
* instead of '?' for a missing argument
*
* optArgument - Points to an options argument (NULL otherwise)
* optChar - Contains the last tested character
* (i.e. the failing one for an unrecognized option)
* optIndex - contains the index to the next (first non-option) argument
*
* Differences to getopt():
* o No error messages printed
* o No argv[] shuffling
* o No special characters '+' or '-' as first options character
*
*/
extern int optIndex;
extern char *optArgument;
extern char optChar;
extern int parseOptions (int argc, char * const argv[], const char *options);
/*
* no additions below this endif
*/
#endif /* ifndef INCLparseOptionsh */

View File

@@ -21,10 +21,6 @@
#include <string.h>
#include <malloc.h>
#if defined(_WIN32)
#include <getopt.h>
#endif
#define epicsAlarmGLOBAL
#include <alarm.h>
#undef epicsAlarmGLOBAL