Added parseOptions to add getopt() functionality (and allow compiling on WIN32)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
88
src/catools/parseOptions.c
Normal file
88
src/catools/parseOptions.c
Normal 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 '?';
|
||||
}
|
||||
58
src/catools/parseOptions.h
Normal file
58
src/catools/parseOptions.h
Normal 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 */
|
||||
@@ -21,10 +21,6 @@
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#define epicsAlarmGLOBAL
|
||||
#include <alarm.h>
|
||||
#undef epicsAlarmGLOBAL
|
||||
|
||||
Reference in New Issue
Block a user