Merge remote-tracking branch 'github/7.0' into 7.0
* github/7.0: Unify doxygen keywords to use '\' not '@' Applied all doxy-libcom changes to latest headers # Conflicts: # modules/libcom/src/yajl/yajl_common.h
This commit is contained in:
@@ -6,8 +6,15 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*asTrapWrite.h*/
|
||||
/* Author: Marty Kraimer Date: 07NOV2000 */
|
||||
|
||||
/**
|
||||
* \file asTrapWrite.h
|
||||
* \brief API for monitoring external put operations to an IOC.
|
||||
* \author Marty Kraimer
|
||||
*
|
||||
* The access security subsystem provides an API asTrapWrite that makes
|
||||
* put/write requests visible to any facility that registers a listener.
|
||||
*/
|
||||
|
||||
#ifndef INCasTrapWriteh
|
||||
#define INCasTrapWriteh
|
||||
@@ -18,37 +25,68 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The message passed to registered listeners.
|
||||
*/
|
||||
typedef struct asTrapWriteMessage {
|
||||
const char *userid;
|
||||
const char *hostid;
|
||||
const char *userid; /**< \brief Userid of whoever orginated the request. */
|
||||
const char *hostid; /**< \brief Hostid of whoever orginated the request. */
|
||||
/** \brief A field for use by the server.
|
||||
*
|
||||
* Any listener that uses this field must know what type of
|
||||
* server is forwarding the put requests. This pointer holds
|
||||
* the value the server provides to asTrapWriteWithData(), which
|
||||
* for RSRV is the dbChannel pointer for the target field.
|
||||
*/
|
||||
void *serverSpecific;
|
||||
/** \brief A field for use by the \ref asTrapWriteListener.
|
||||
*
|
||||
* When the listener is called before the write, this has the
|
||||
* value 0. The listener can give it any value it desires
|
||||
* and it will have the same value when the listener gets
|
||||
* called again after the write.
|
||||
*/
|
||||
void *userPvt;
|
||||
int dbrType; /* Data type from ca/db_access.h, NOT dbFldTypes.h */
|
||||
int no_elements;
|
||||
void *data; /* Might be NULL if no data is available */
|
||||
int dbrType; /**< \brief Data type from ca/db_access.h, NOT dbFldTypes.h */
|
||||
int no_elements; /**< \brief Array length */
|
||||
void *data; /**< \brief Might be NULL if no data is available */
|
||||
} asTrapWriteMessage;
|
||||
|
||||
|
||||
/**
|
||||
* \brief An identifier needed to unregister an listener.
|
||||
*/
|
||||
typedef void *asTrapWriteId;
|
||||
|
||||
/**
|
||||
* \brief Pointer to a listener function.
|
||||
*
|
||||
* Each registered listener function is called twice for every put; once
|
||||
* before and once after the write is performed.
|
||||
* The listener may set \c userPvt in the first call and retrieve it in the
|
||||
* second call.
|
||||
*
|
||||
* Each asTrapWriteMessage can change or may be deleted after the user's
|
||||
* asTrapWriteListener returns
|
||||
*
|
||||
* The listener function is called by a server thread so it must not block
|
||||
* or do anything that causes a delay.
|
||||
*/
|
||||
typedef void(*asTrapWriteListener)(asTrapWriteMessage *pmessage,int after);
|
||||
|
||||
/**
|
||||
* \brief Register function to be called on asTrapWriteListener.
|
||||
* \param func The listener function to be called.
|
||||
* \return A listener identifier for unregistering this listener.
|
||||
*/
|
||||
epicsShareFunc asTrapWriteId epicsShareAPI asTrapWriteRegisterListener(
|
||||
asTrapWriteListener func);
|
||||
/**
|
||||
* \brief Unregister asTrapWriteListener.
|
||||
* \param id Listener identifier from asTrapWriteRegisterListener().
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI asTrapWriteUnregisterListener(
|
||||
asTrapWriteId id);
|
||||
|
||||
/*
|
||||
* asTrapWriteListener is called before and after the write is performed.
|
||||
* The listener can set userPvt on the before call and retrieve it after
|
||||
* after = (0,1) (before,after) the put.
|
||||
*
|
||||
* Each asTrapWriteMessage can change or may be deleted after
|
||||
* the user's asTrapWriteListener returns
|
||||
*
|
||||
* asTrapWriteListener delays the associated server thread so it must not
|
||||
* do anything that causes to to block.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Jeffrey O. Hill
|
||||
* hill@luke.lanl.gov
|
||||
* (505) 665 1831
|
||||
* Date: 9-93
|
||||
/**
|
||||
* \file bucketLib.h
|
||||
* \author Jeffrey O. Hill
|
||||
* \brief A hash table. Do not use for new code.
|
||||
*
|
||||
* NOTES:
|
||||
* .01 Storage for identifier must persist until an item is deleted
|
||||
* \details
|
||||
* A hash table for which keys may be unsigned integers, pointers, or
|
||||
* strings. This API is used by the IOC's Channel Access Server, but
|
||||
* it should not be used by other code.
|
||||
*
|
||||
* \note Storage for identifiers must persist until an item is deleted
|
||||
*/
|
||||
|
||||
#ifndef INCbucketLibh
|
||||
@@ -27,10 +30,13 @@ extern "C" {
|
||||
#include "epicsTypes.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
/** \brief Internal: bucket identifier */
|
||||
typedef unsigned BUCKETID;
|
||||
|
||||
/** \brief Internal: bucket key type */
|
||||
typedef enum {bidtUnsigned, bidtPointer, bidtString} buckTypeOfId;
|
||||
|
||||
/** \brief Internal: bucket item structure */
|
||||
typedef struct item{
|
||||
struct item *pItem;
|
||||
const void *pId;
|
||||
@@ -38,6 +44,7 @@ typedef struct item{
|
||||
buckTypeOfId type;
|
||||
}ITEM;
|
||||
|
||||
/** \brief Internal: Hash table structure */
|
||||
typedef struct bucket{
|
||||
ITEM **pTable;
|
||||
void *freeListPVT;
|
||||
@@ -45,47 +52,147 @@ typedef struct bucket{
|
||||
unsigned hashIdNBits;
|
||||
unsigned nInUse;
|
||||
}BUCKET;
|
||||
|
||||
epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries);
|
||||
epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb);
|
||||
epicsShareFunc int epicsShareAPI bucketShow (BUCKET *pb);
|
||||
|
||||
/*
|
||||
* !! Identifier must exist (and remain constant) at the specified address until
|
||||
* the item is deleted from the bucket !!
|
||||
/**
|
||||
* \brief Creates a new hash table
|
||||
* \param nHashTableEntries Table size
|
||||
* \return Pointer to the newly created hash table, or NULL.
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemUnsignedId (BUCKET *prb,
|
||||
epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries);
|
||||
/**
|
||||
* \brief Release memory used by a hash table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \return S_bucket_success
|
||||
* \note All items must be deleted from the hash table before calling this.
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb);
|
||||
/**
|
||||
* \brief Display information about a hash table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \return S_bucket_success
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketShow (BUCKET *prb);
|
||||
|
||||
/**
|
||||
* \brief Add an item identified by an unsigned int to the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \param *pApp Pointer to the payload
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemUnsignedId (BUCKET *prb,
|
||||
const unsigned *pId, const void *pApp);
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemPointerId (BUCKET *prb,
|
||||
/**
|
||||
* \brief Add an item identified by a pointer to the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \param *pApp Pointer to the payload
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemPointerId (BUCKET *prb,
|
||||
void * const *pId, const void *pApp);
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemStringId (BUCKET *prb,
|
||||
/**
|
||||
* \brief Add an item identified by a string to the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \param *pApp Pointer to the payload
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketAddItemStringId (BUCKET *prb,
|
||||
const char *pId, const void *pApp);
|
||||
|
||||
/**
|
||||
* \brief Remove an item identified by a string from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId);
|
||||
/**
|
||||
* \brief Remove an item identified by a pointer from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketRemoveItemPointerId (BUCKET *prb, void * const *pId);
|
||||
/**
|
||||
* \brief Remove an item identified by a string from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Status value
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI bucketRemoveItemStringId (BUCKET *prb, const char *pId);
|
||||
|
||||
/**
|
||||
* \brief Find an item identified by an unsigned int in the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId);
|
||||
/**
|
||||
* \brief Find an item identified by a pointer in the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupItemPointerId (BUCKET *prb, void * const *pId);
|
||||
/**
|
||||
* \brief Find an item identified by a string in the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupItemStringId (BUCKET *prb, const char *pId);
|
||||
|
||||
/**
|
||||
* \brief Find and delete an item identified by an unsigned int from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId);
|
||||
/**
|
||||
* \brief Find and delete an item identified by a pointer from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemPointerId (BUCKET *prb, void * const *pId);
|
||||
/**
|
||||
* \brief Find and delete an item identified by a string from the table
|
||||
* \param *prb Pointer to the hash table
|
||||
* \param *pId Pointer to the identifier
|
||||
* \return Item's payload pointer, or NULL if not found
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemStringId (BUCKET *prb, const char *pId);
|
||||
|
||||
|
||||
/*
|
||||
* Status returned by bucketLib functions
|
||||
/**
|
||||
* \name Status values returned by some bucketLib functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief A synonym for S_bucket_success
|
||||
*/
|
||||
#define BUCKET_SUCCESS S_bucket_success
|
||||
/**
|
||||
* \brief Success, must be 0.
|
||||
*/
|
||||
#define S_bucket_success 0
|
||||
/**
|
||||
* \brief Memory allocation failed
|
||||
*/
|
||||
#define S_bucket_noMemory (M_bucket | 1) /*Memory allocation failed*/
|
||||
/**
|
||||
* \brief Identifier already in use
|
||||
*/
|
||||
#define S_bucket_idInUse (M_bucket | 2) /*Identifier already in use*/
|
||||
/**
|
||||
* \brief Unknown identifier
|
||||
*/
|
||||
#define S_bucket_uknId (M_bucket | 3) /*Unknown identifier*/
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*INCbucketLibh*/
|
||||
|
||||
|
||||
@@ -4,11 +4,16 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* postfix.h
|
||||
* Original Author: Bob Dalesio
|
||||
* Date: 9-21-88
|
||||
/**
|
||||
* \file postfix.h
|
||||
* \author Bob Dalesio, Andrew Johnson
|
||||
*
|
||||
* \brief The API for the EPICS Calculation Engine
|
||||
*
|
||||
* Defines macros and the routines provided by the calculation engine for
|
||||
* subsystems that need to evaluate mathematical expressions.
|
||||
*/
|
||||
|
||||
#ifndef INCpostfixh
|
||||
@@ -16,69 +21,340 @@
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/** \brief Number of input arguments to a calc expression (A-L) */
|
||||
#define CALCPERFORM_NARGS 12
|
||||
/** \brief Size of the internal partial result stack */
|
||||
#define CALCPERFORM_STACK 80
|
||||
|
||||
#define INFIX_TO_POSTFIX_SIZE(n) ((n)*21/6)
|
||||
/* The above expression is an estimate of the maximum postfix buffer
|
||||
* size needed for a given infix expression buffer (the argument must count
|
||||
* the trailing nil byte in the input expression string). The actual size
|
||||
/**
|
||||
* \name Postfix and Infix Buffer Sizes
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Calculate required size of postfix buffer from infix
|
||||
*
|
||||
* This macro calculates the maximum size of postfix buffer needed for an
|
||||
* infix expression buffer of a given size. The argument \c n must count
|
||||
* the trailing nil byte in the input expression string. The actual size
|
||||
* needed is never larger than this value, although it is actually a
|
||||
* few bytes smaller for some sizes.
|
||||
*
|
||||
* The maximum expansion from infix to postfix is for the sub-expression
|
||||
* .1?.1:
|
||||
\code
|
||||
.1?.1:
|
||||
\endcode
|
||||
* which is 6 characters long and results in 21 bytes of postfix:
|
||||
* .1 => LITERAL_DOUBLE + 8 byte value
|
||||
* ? => COND_IF
|
||||
* .1 => LITERAL_DOUBLE + 8 byte value
|
||||
* : => COND_ELSE
|
||||
* ...
|
||||
* => COND_END
|
||||
\code
|
||||
.1 => LITERAL_DOUBLE + 8 byte value
|
||||
? => COND_IF
|
||||
.1 => LITERAL_DOUBLE + 8 byte value
|
||||
: => COND_ELSE
|
||||
...
|
||||
=> COND_END
|
||||
\endcode
|
||||
* For other short expressions the factor 21/6 always gives a big enough
|
||||
* postfix buffer (proven by hand, look at '1+' and '.1+' as well).
|
||||
*/
|
||||
#define INFIX_TO_POSTFIX_SIZE(n) ((n)*21/6)
|
||||
|
||||
/* These are not hard limits, just default sizes for the database */
|
||||
/**
|
||||
* \brief Size of a "standard" infix string.
|
||||
*
|
||||
* This is not a hard limit, just the default size for the database
|
||||
*/
|
||||
#define MAX_INFIX_SIZE 100
|
||||
/**
|
||||
* \brief Size of a "standard" postfix buffer.
|
||||
*
|
||||
* This is not a hard limit, just the default size for the database
|
||||
*/
|
||||
#define MAX_POSTFIX_SIZE INFIX_TO_POSTFIX_SIZE(MAX_INFIX_SIZE)
|
||||
|
||||
/** @} */
|
||||
|
||||
/* Error numbers from postfix */
|
||||
/** \name Calc Engine Error Codes
|
||||
* \note Changes in these errors must also be made in calcErrorStr().
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define CALC_ERR_NONE 0 /* No error */
|
||||
#define CALC_ERR_TOOMANY 1 /* Too many results returned */
|
||||
#define CALC_ERR_BAD_LITERAL 2 /* Bad numeric literal */
|
||||
#define CALC_ERR_BAD_ASSIGNMENT 3 /* Bad assignment target */
|
||||
#define CALC_ERR_BAD_SEPERATOR 4 /* Comma without parentheses */
|
||||
#define CALC_ERR_PAREN_NOT_OPEN 5 /* Close parenthesis without open */
|
||||
#define CALC_ERR_PAREN_OPEN 6 /* Open parenthesis at end of expression */
|
||||
#define CALC_ERR_CONDITIONAL 7 /* Unbalanced conditional ?: operators */
|
||||
#define CALC_ERR_INCOMPLETE 8 /* Incomplete expression, operand missing */
|
||||
#define CALC_ERR_UNDERFLOW 9 /* Runtime stack would underflow */
|
||||
#define CALC_ERR_OVERFLOW 10 /* Runtime stack would overflow */
|
||||
#define CALC_ERR_SYNTAX 11 /* Syntax error */
|
||||
#define CALC_ERR_NULL_ARG 12 /* NULL or empty input argument */
|
||||
#define CALC_ERR_INTERNAL 13 /* Internal error, bad element type */
|
||||
/* Changes in the above errors must also be made in calcErrorStr() */
|
||||
/** \brief No error */
|
||||
#define CALC_ERR_NONE 0
|
||||
/** \brief Too many results returned */
|
||||
#define CALC_ERR_TOOMANY 1
|
||||
/** \brief Bad numeric literal */
|
||||
#define CALC_ERR_BAD_LITERAL 2
|
||||
/** \brief Bad assignment target */
|
||||
#define CALC_ERR_BAD_ASSIGNMENT 3
|
||||
/** \brief Comma without parentheses */
|
||||
#define CALC_ERR_BAD_SEPERATOR 4
|
||||
/** \brief Close parenthesis without open */
|
||||
#define CALC_ERR_PAREN_NOT_OPEN 5
|
||||
/** \brief Open parenthesis at end of expression */
|
||||
#define CALC_ERR_PAREN_OPEN 6
|
||||
/** \brief Unbalanced conditional ?: operators */
|
||||
#define CALC_ERR_CONDITIONAL 7
|
||||
/** \brief Incomplete expression, operand missing */
|
||||
#define CALC_ERR_INCOMPLETE 8
|
||||
/** \brief Runtime stack would underflow */
|
||||
#define CALC_ERR_UNDERFLOW 9
|
||||
/** \brief Runtime stack would overflow */
|
||||
#define CALC_ERR_OVERFLOW 10
|
||||
/** \brief Syntax error */
|
||||
#define CALC_ERR_SYNTAX 11
|
||||
/** \brief NULL or empty input argument */
|
||||
#define CALC_ERR_NULL_ARG 12
|
||||
/** \brief Internal error, bad element type */
|
||||
#define CALC_ERR_INTERNAL 13
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Compile an infix expression into postfix byte-code
|
||||
*
|
||||
* Converts an expression from an infix string to postfix byte-code
|
||||
*
|
||||
* \param pinfix Pointer to the infix string
|
||||
* \param ppostfix Pointer to the postfix buffer
|
||||
* \param perror Place to return an error code
|
||||
* \return Non-zero value in event of error
|
||||
*
|
||||
* It is the callers's responsibility to ensure that \c ppostfix points
|
||||
* to sufficient storage to hold the postfix expression. The macro
|
||||
* INFIX_TO_POSTFIX_SIZE(n) can be used to calculate an appropriate
|
||||
* postfix buffer size from the length of the infix buffer.
|
||||
*
|
||||
* \note "n" must count the terminating nil byte too.
|
||||
*
|
||||
* -# The **infix expressions** that can be used are very similar
|
||||
* to the C expression syntax, but with some additions and subtle
|
||||
* differences in operator meaning and precedence. The string may
|
||||
* contain a series of expressions separated by a semi-colon character ';'
|
||||
* any one of which may actually provide the calculation result; however
|
||||
* all of the other expressions included must assign their result to
|
||||
* a variable. All alphabetic elements described below are case independent,
|
||||
* so upper and lower case letters may be used and mixed in the variable
|
||||
* and function names as desired. Spaces may be used anywhere within an
|
||||
* expression except between the characters that make up a single expression element.
|
||||
*
|
||||
* -# ***Numeric Literals***
|
||||
* The simplest expression element is a numeric literal, any (positive)
|
||||
* number expressed using the standard floating point syntax that can be stored
|
||||
* as a double precision value. This now includes the values Infinity and
|
||||
* NaN (not a number). Note that negative numbers will be encoded as a
|
||||
* positive literal to which the unary negate operator is applied.
|
||||
*
|
||||
* - Examples:
|
||||
* - 1
|
||||
* - 2.718281828459
|
||||
* - Inf
|
||||
*
|
||||
* -# ***Constants***
|
||||
* There are three trigonometric constants available to any expression
|
||||
* which return a value:
|
||||
* - pi returns the value of the mathematical constant pi.
|
||||
* - D2R evaluates to pi/180 which, when used as a multiplier,
|
||||
* converts an angle from degrees to radians.
|
||||
* - R2D evaluates to 180/pi which as a multiplier converts an angle
|
||||
* from radians to degrees.
|
||||
*
|
||||
* -# ***Variables***
|
||||
* Variables are used to provide inputs to an expression, and are named
|
||||
* using the single letters A through L inclusive or the keyword VAL which
|
||||
* refers to the previous result of this calculation. The software that
|
||||
* makes use of the expression evaluation code should document how the
|
||||
* individual variables are given values; for the calc record type the input
|
||||
* links INPA through INPL can be used to obtain these from other record fields,
|
||||
* and VAL refers to the the VAL field (which can be overwritten from outside
|
||||
* the record via Channel Access or a database link).
|
||||
*
|
||||
* -# ***Variable Assignment Operator***
|
||||
* Recently added is the ability to assign the result of a sub-expression to
|
||||
* any of the single letter variables, which can then be used in another
|
||||
* sub-expression. The variable assignment operator is the character pair
|
||||
* := and must immediately follow the name of the variable to receive the
|
||||
* expression value. Since the infix string must return exactly one value, every
|
||||
* expression string must have exactly one sub-expression that is not an
|
||||
* assignment, which can appear anywhere in the string. Sub-expressions within
|
||||
* the string are separated by a semi-colon character.
|
||||
*
|
||||
* - Examples:
|
||||
* - B; B:=A
|
||||
* - i:=i+1; a*sin(i*D2R)
|
||||
*
|
||||
* -# ***Arithmetic Operators***
|
||||
* The usual binary arithmetic operators are provided: + - * and / with their
|
||||
* usual relative precedence and left-to-right associativity, and - may also
|
||||
* be used as a unary negate operator where it has a higher precedence and
|
||||
* associates from right to left. There is no unary plus operator, so numeric
|
||||
* literals cannot begin with a + sign.
|
||||
*
|
||||
* - Examples:
|
||||
* - a*b + c
|
||||
* - a/-4 - b
|
||||
*
|
||||
* Three other binary operators are also provided: % is the integer modulo operator,
|
||||
* while the synonymous operators ** and ^ raise their left operand to the power of
|
||||
* the right operand. % has the same precedence and associativity as * and /, while
|
||||
* the power operators associate left-to-right and have a precedence in between * and
|
||||
* unary minus.
|
||||
*
|
||||
* - Examples:
|
||||
* - e:=a%10;
|
||||
* - d:=a/10%10;
|
||||
* - c:=a/100%10;
|
||||
* - b:=a/1000%10;
|
||||
* - b*4096+c*256+d*16+e
|
||||
* - sqrt(a**2 + b**2)
|
||||
*
|
||||
* -# ***Algebraic Functions***
|
||||
* Various algebraic functions are available which take parameters inside
|
||||
* parentheses. The parameter seperator is a comma.
|
||||
*
|
||||
* - Absolute value: abs(a)
|
||||
* - Exponential ea: exp(a)
|
||||
* - Logarithm, base 10: log(a)
|
||||
* - Natural logarithm (base e): ln(a) or loge(a)
|
||||
* - n parameter maximum value: max(a, b, ...)
|
||||
* - n parameter minimum value: min(a, b, ...)
|
||||
* - Square root: sqr(a) or sqrt(a)
|
||||
*
|
||||
* -# ***Trigonometric Functions***
|
||||
* Standard circular trigonometric functions, with angles expressed in radians:
|
||||
* - Sine: sin(a)
|
||||
* - Cosine: cos(a)
|
||||
* - Tangent: tan(a)
|
||||
* - Arcsine: asin(a)
|
||||
* - Arccosine: acos(a)
|
||||
* - Arctangent: atan(a)
|
||||
* - 2 parameter arctangent: atan2(a, b)
|
||||
* \note Note that these arguments are the reverse of the ANSI C function,
|
||||
* so while C would return arctan(a/b) the calc expression engine returns arctan(b/a)
|
||||
*
|
||||
* -# ***Hyperbolic Trigonometry***
|
||||
* The basic hyperbolic functions are provided, but no inverse functions
|
||||
* (which are not provided by the ANSI C math library either).
|
||||
* - Hyperbolic sine: sinh(a)
|
||||
* - Hyperbolic cosine: cosh(a)
|
||||
* - Hyperbolic tangent: tanh(a)
|
||||
*
|
||||
* -# ***Numeric Functions***
|
||||
* The numeric functions perform operations related to the floating point
|
||||
* numeric representation and truncation or rounding.
|
||||
* - Round up to next integer: ceil(a)
|
||||
* - Round down to next integer: floor(a)
|
||||
* - Round to nearest integer: nint(a)
|
||||
* - Test for infinite result: isinf(a)
|
||||
* - Test for any non-numeric values: isnan(a, ...)
|
||||
* - Test for all finite, numeric values: finite(a, ...)
|
||||
* - Random number between 0 and 1: rndm
|
||||
*
|
||||
* -# ***Boolean Operators***
|
||||
* These operators regard their arguments as true or false, where 0.0 is
|
||||
* false and any other value is true.
|
||||
*
|
||||
* - Boolean and: a && b
|
||||
* - Boolean or: a || b
|
||||
* - Boolean not: !a
|
||||
*
|
||||
* -# ***Bitwise Operators***
|
||||
* The bitwise operators convert their arguments to an integer (by truncation),
|
||||
* perform the appropriate bitwise operation and convert back to a floating point
|
||||
* value. Unlike in C though, ^ is not a bitwise exclusive-or operator.
|
||||
*
|
||||
* - Bitwise and: a & b or a and b
|
||||
* - Bitwise or: a | b or a or b
|
||||
* - Bitwise exclusive or: a xor b
|
||||
* - Bitwise not (ones complement): ~a or not a
|
||||
* - Bitwise left shift: a << b
|
||||
* - Bitwise right shift: a >> b
|
||||
*
|
||||
* -# ***Relational Operators***
|
||||
* Standard numeric comparisons between two values:
|
||||
*
|
||||
* - Less than: a < b
|
||||
* - Less than or equal to: a <= b
|
||||
* - Equal to: a = b or a == b
|
||||
* - Greater than or equal to: a >= b
|
||||
* - Greater than: a > b
|
||||
* - Not equal to: a != b or a # b
|
||||
*
|
||||
* -# ***Conditional Operator***
|
||||
* Expressions can use the C conditional operator, which has a lower
|
||||
* precedence than all of the other operators except for the assignment operator.
|
||||
*
|
||||
* - condition ? true result : false result
|
||||
* - Example:
|
||||
* - a < 360 ? a+1 : 0
|
||||
*
|
||||
* -# ***Parentheses***
|
||||
* Sub-expressions can be placed within parentheses to override operator precence rules.
|
||||
* Parentheses can be nested to any depth, but the intermediate value stack used by
|
||||
* the expression evaluation engine is limited to 80 results (which require an
|
||||
* expression at least 321 characters long to reach).
|
||||
*/
|
||||
epicsShareFunc long
|
||||
postfix(const char *pinfix, char *ppostfix, short *perror);
|
||||
|
||||
/** \brief Run the calculation engine
|
||||
*
|
||||
* Evaluates the postfix expression against a set ot input values.
|
||||
*
|
||||
* \param parg Pointer to an array of double values for the arguments A-L
|
||||
* that can appear in the expression. Note that the argument values may be
|
||||
* modified if the expression uses the assignment operator.
|
||||
* \param presult Where to put the calculated result, which may be a NaN or Infinity.
|
||||
* \param ppostfix The postfix expression created by postfix().
|
||||
* \return Status value 0 for OK, or non-zero if an error is discovered
|
||||
* during the evaluation process.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
calcPerform(double *parg, double *presult, const char *ppostfix);
|
||||
|
||||
/** \brief Find the inputs and outputs of an expression
|
||||
*
|
||||
* Software using the calc subsystem may need to know what expression
|
||||
* arguments are used and/or modified by a particular expression. It can
|
||||
* discover this from the postfix string by calling calcArgUsage(), which
|
||||
* takes two pointers \c pinputs and \c pstores to a pair of unsigned long
|
||||
* bitmaps which return that information to the caller. Passing a NULL value
|
||||
* for either of these pointers is legal if only the other is needed.
|
||||
*
|
||||
* The least signficant bit (bit 0) of the bitmap at \c *pinputs will be set
|
||||
* if the expression depends on the argument A, and so on through bit 11 for
|
||||
* the argument L. An argument that is not used until after a value has been
|
||||
* assigned to it will not be set in the pinputs bitmap, thus the bits can
|
||||
* be used to determine whether a value needs to be supplied for their
|
||||
* associated argument or not for the purposes of evaluating the expression.
|
||||
*
|
||||
* Bit 0 of the bitmap at \c *pstores will be set if the expression assigns
|
||||
* a value to the argument A, bit 1 for argument B etc.
|
||||
* \param ppostfix A postfix expression created by postfix().
|
||||
* \param pinputs Bitmap pointer.
|
||||
* \param pstores Bitmap pointer.
|
||||
* \return The return value will be non-zero if the ppostfix expression was
|
||||
* illegal, otherwise 0.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
calcArgUsage(const char *ppostfix, unsigned long *pinputs, unsigned long *pstores);
|
||||
|
||||
/** \brief Convert an error code to a string.
|
||||
*
|
||||
* Gives out a printable version of an individual error code.
|
||||
* The error codes are macros defined here with names starting \c CALC_ERR_
|
||||
* \param error Error code
|
||||
* \return A string representation of the error code
|
||||
*/
|
||||
epicsShareFunc const char *
|
||||
calcErrorStr(short error);
|
||||
|
||||
/** \brief Disassemble a postfix expression
|
||||
*
|
||||
* Convert the byte-code stream to text and print to stdout.
|
||||
* \param pinst postfix instructions
|
||||
*/
|
||||
epicsShareFunc void
|
||||
calcExprDump(const char *pinst);
|
||||
|
||||
|
||||
@@ -3,71 +3,105 @@
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
// epicsAlgorithm.h
|
||||
// Authors: Jeff Hill & Andrew Johnson
|
||||
/**
|
||||
* \file epicsAlgorithm.h
|
||||
* \author Jeff Hill & Andrew Johnson
|
||||
*
|
||||
* \brief Contains a few templates out of the C++ standard header algorithm
|
||||
*
|
||||
* \note The templates are provided here in a much smaller file. Standard algorithm
|
||||
* contains many templates for sorting and searching through C++ template containers
|
||||
* which are not used in EPICS. If all you need from there is std::min(),
|
||||
* std::max() and/or std::swap() your code may compile faster if you include
|
||||
* epicsAlgorithm.h and use epicsMin(), epicsMax() and epicsSwap() instead.
|
||||
*
|
||||
* The C++ standard only requires types to be less-than comparable, so
|
||||
* the epicsMin and epicsMax templates only use operator <.
|
||||
*/
|
||||
|
||||
#ifndef __EPICS_ALGORITHM_H__
|
||||
#define __EPICS_ALGORITHM_H__
|
||||
|
||||
#include "epicsMath.h"
|
||||
|
||||
// The C++ standard only requires types to be less-than comparable, so
|
||||
// the epicsMin and epicsMax templates only use operator <
|
||||
|
||||
// epicsMin
|
||||
|
||||
/**
|
||||
* Returns the smaller of a or b compared using a<b.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
inline const T& epicsMin (const T& a, const T& b)
|
||||
{
|
||||
return (b < a) ? b : a;
|
||||
}
|
||||
|
||||
// If b is a NaN the above template returns a, but should return NaN.
|
||||
// These specializations ensure that epicsMin(x,NaN) == NaN
|
||||
|
||||
/**
|
||||
* Returns the smaller of a or b compared using a<b.
|
||||
*
|
||||
* \note If b is a NaN the above template returns a, but should return NaN.
|
||||
* These specializations ensure that epicsMin(x,NaN) == NaN
|
||||
*/
|
||||
template <>
|
||||
inline const float& epicsMin (const float& a, const float& b)
|
||||
{
|
||||
return (b < a) || isnan(b) ? b : a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smaller of a or b compared using a<b.
|
||||
*
|
||||
* \note If b is a NaN the above template returns a, but should return NaN.
|
||||
* These specializations ensure that epicsMin(x,NaN) == NaN
|
||||
*/
|
||||
template <>
|
||||
inline const double& epicsMin (const double& a, const double& b)
|
||||
{
|
||||
return (b < a) || isnan(b) ? b : a;
|
||||
}
|
||||
|
||||
|
||||
// epicsMax
|
||||
|
||||
/**
|
||||
* Returns the larger of a or b compared using a<b.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
inline const T& epicsMax (const T& a, const T& b)
|
||||
{
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
// If b is a NaN the above template returns a, but should return NaN.
|
||||
// These specializations ensure that epicsMax(x,NaN) == NaN
|
||||
|
||||
/**
|
||||
* Returns the larger of a or b compared using a<b.
|
||||
*
|
||||
* \note If b is a NaN the above template returns a, but should return NaN.
|
||||
* These specializations ensure that epicsMax(x,NaN) == NaN
|
||||
*/
|
||||
template <>
|
||||
inline const float& epicsMax (const float& a, const float& b)
|
||||
{
|
||||
return (a < b) || isnan(b) ? b : a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the larger of a or b compared using a<b.
|
||||
*
|
||||
* \note If b is a NaN the above template returns a, but should return NaN.
|
||||
* These specializations ensure that epicsMax(x,NaN) == NaN
|
||||
*/
|
||||
template <>
|
||||
inline const double& epicsMax (const double& a, const double& b)
|
||||
{
|
||||
return (a < b) || isnan(b) ? b : a;
|
||||
}
|
||||
|
||||
|
||||
// epicsSwap
|
||||
|
||||
/**
|
||||
* Swaps the values of a and b.
|
||||
*
|
||||
* \note The data type must support both copy-construction and assignment.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
inline void epicsSwap(T& a, T& b)
|
||||
{
|
||||
|
||||
@@ -3,15 +3,33 @@
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Jim Kowalkowski and Marty Kraimer
|
||||
* Date: 4/97
|
||||
|
||||
/**
|
||||
* \file dbmf.h
|
||||
* \author Jim Kowalkowski, Marty Kraimer
|
||||
*
|
||||
* A library to manage storage that is allocated and then freed.
|
||||
* \brief A library to manage storage that is allocated and quickly freed.
|
||||
*
|
||||
* Database Macro/Free describes a facility that prevents memory fragmentation
|
||||
* when temporary storage is being allocated and freed a short time later, at
|
||||
* the same time that much longer-lived storage is also being allocated, such
|
||||
* as when parsing items for the IOC database while also creating records.
|
||||
*
|
||||
* Routines whin iocCore like dbLoadDatabase() have the following attributes:
|
||||
* - They repeatedly call malloc() followed soon afterwards by a call to
|
||||
* free() the temporaryily allocated storage.
|
||||
* - Between those calls to malloc() and free(), additional calls to
|
||||
* malloc() are made that do NOT have an associated free().
|
||||
*
|
||||
* \note In some environment, e.g. vxWorks, this behavior causes severe memory
|
||||
* fragmentation.
|
||||
*
|
||||
* \note This facility should NOT be used by code that allocates storage and
|
||||
* then keeps it for a considerable period of time before releasing. Such code
|
||||
* should consider using the freeList library.
|
||||
*/
|
||||
#ifndef DBMF_H
|
||||
#define DBMF_H
|
||||
@@ -23,25 +41,71 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize the facility
|
||||
* \param size The maximum size request from dbmfMalloc() that will be
|
||||
* allocated from the dbmf pool (Size is always made a multiple of 8).
|
||||
* \param chunkItems Each time malloc() must be called size*chunkItems bytes
|
||||
* are allocated.
|
||||
* \return 0 on success, -1 if already initialized
|
||||
*
|
||||
* \note If dbmfInit() is not called before one of the other routines then it
|
||||
* is automatically called with size=64 and chunkItems=10
|
||||
*/
|
||||
epicsShareFunc int dbmfInit(size_t size, int chunkItems);
|
||||
/**
|
||||
* \brief Allocate memory.
|
||||
* \param bytes If bytes > size then malloc() is used to allocate the memory.
|
||||
* \return Pointer to the newly-allocated memory, or NULL on failure.
|
||||
*/
|
||||
epicsShareFunc void * dbmfMalloc(size_t bytes);
|
||||
/**
|
||||
* \brief Duplicate a string.
|
||||
*
|
||||
* Create a copy of the input string.
|
||||
* \param str Pointer to the null-terminated string to be copied.
|
||||
* \return A pointer to the new copy, or NULL on failure.
|
||||
*/
|
||||
epicsShareFunc char * dbmfStrdup(const char *str);
|
||||
/**
|
||||
* \brief Duplicate a string (up to len bytes).
|
||||
*
|
||||
* Copy at most len bytes of the input string into a new buffer. If no nil
|
||||
* terminator is seen in the first \c len bytes a nil terminator is added.
|
||||
* \param str Pointer to the null-terminated string to be copied.
|
||||
* \param len Max number of bytes to copy.
|
||||
* \return A pointer to the new string, or NULL on failure.
|
||||
*/
|
||||
epicsShareFunc char * dbmfStrndup(const char *str, size_t len);
|
||||
/**
|
||||
* \brief Concatenate three strings.
|
||||
|
||||
* Returns a pointer to a null-terminated string made by concatenating the
|
||||
* three input strings.
|
||||
* \param lhs Start string to which the others get concatenated to (left part).
|
||||
* \param mid Next string to be concatenated to the lhs (mid part).
|
||||
* \param rhs Last string to be concatenated to the lhs+mid (right part).
|
||||
* \return A pointer to the new string, or NULL on failure.
|
||||
*/
|
||||
epicsShareFunc char * dbmfStrcat3(const char *lhs, const char *mid,
|
||||
const char *rhs);
|
||||
/**
|
||||
* \brief Free the memory allocated by dbmfMalloc.
|
||||
* \param bytes Pointer to memory obtained from dbmfMalloc(), dbmfStrdup(),
|
||||
* dbmfStrndup() or dbmfStrcat3().
|
||||
*/
|
||||
epicsShareFunc void dbmfFree(void *bytes);
|
||||
/**
|
||||
* \brief Free all chunks that contain only free items.
|
||||
*/
|
||||
epicsShareFunc void dbmfFreeChunks(void);
|
||||
/**
|
||||
* \brief Show the status of the dbmf memory pool.
|
||||
* \param level Detail level.
|
||||
* \return 0.
|
||||
*/
|
||||
epicsShareFunc int dbmfShow(int level);
|
||||
|
||||
/* Rules:
|
||||
* 1) Size is always made a multiple of 8.
|
||||
* 2) if dbmfInit is not called before one of the other routines then it
|
||||
* is automatically called with size=64 and chunkItems=10
|
||||
* 3) These routines should only be used to allocate storage that will
|
||||
* shortly thereafter be freed.
|
||||
* 4) dbmfFreeChunks can only free chunks that contain only free items
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,10 +6,23 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: John Winans (ANL)
|
||||
* Andrew Johnson <anj@aps.anl.gov>
|
||||
/**
|
||||
* \file ellLib.h
|
||||
* \author John Winans (ANL)
|
||||
* \author Andrew Johnson (ANL)
|
||||
*
|
||||
* \brief A doubly-linked list library
|
||||
*
|
||||
* This provides similar functionality to the VxWorks lstLib library.
|
||||
*
|
||||
* Supports the creation and maintenance of a doubly-linked list. The user
|
||||
* supplies a list descriptor (type \c ELLLIST) that will contain pointers to
|
||||
* the first and last nodes in the list, and a count of the number of
|
||||
* nodes in the list. The nodes in the list can be any user-defined structure,
|
||||
* but they must reserve space for two pointers as their first elements.
|
||||
* Both the forward and backward chains are terminated with a NULL pointer.
|
||||
*/
|
||||
|
||||
#ifndef INC_ellLib_H
|
||||
#define INC_ellLib_H
|
||||
|
||||
@@ -19,46 +32,182 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief List node type.
|
||||
*
|
||||
* A list node (an \c ELLNODE) must be embedded in the structure to be placed
|
||||
* on the list, ideally as the first member of that structure.
|
||||
*
|
||||
* If the node is elsewhere in the structure, care must be taken to convert
|
||||
* between the structure pointer and the node pointer and back every time when
|
||||
* calling routines in the ellLib API. The ellFree() and ellFree2() routines
|
||||
* cannot be used with such a list.
|
||||
*/
|
||||
typedef struct ELLNODE {
|
||||
struct ELLNODE *next;
|
||||
struct ELLNODE *previous;
|
||||
struct ELLNODE *next; /**< \brief Pointer to next node in list */
|
||||
struct ELLNODE *previous; /**< \brief Pointer to previous node in list */
|
||||
} ELLNODE;
|
||||
|
||||
/** \brief Value of a terminal node
|
||||
*/
|
||||
#define ELLNODE_INIT {NULL, NULL}
|
||||
|
||||
/** \brief List header type
|
||||
*/
|
||||
typedef struct ELLLIST {
|
||||
ELLNODE node;
|
||||
int count;
|
||||
ELLNODE node; /**< \brief Pointers to the first and last nodes on list */
|
||||
int count; /**< \brief Number of nodes on the list */
|
||||
} ELLLIST;
|
||||
|
||||
/** \brief Value of an empty list
|
||||
*/
|
||||
#define ELLLIST_INIT {ELLNODE_INIT, 0}
|
||||
|
||||
/** \brief Pointer to free() for use by ellFree() macro.
|
||||
*
|
||||
* This is required for use on Windows, where each DLL has its own free()
|
||||
* function. The ellFree() macro passes the application's version of free()
|
||||
* to the ellFree2() function.
|
||||
*/
|
||||
typedef void (*FREEFUNC)(void *);
|
||||
|
||||
/** \brief Initialize a list type
|
||||
* \param PLIST Pointer to list header to be initialized
|
||||
*/
|
||||
#define ellInit(PLIST) {\
|
||||
(PLIST)->node.next = (PLIST)->node.previous = NULL;\
|
||||
(PLIST)->count = 0;\
|
||||
}
|
||||
/** \brief Report the number of nodes in a list
|
||||
* \param PLIST Pointer to list descriptor
|
||||
* \return Number of nodes in the list
|
||||
*/
|
||||
#define ellCount(PLIST) ((PLIST)->count)
|
||||
/** \brief Find the first node in list
|
||||
* \param PLIST Pointer to list descriptor
|
||||
* \return Pointer to first node in the list
|
||||
*/
|
||||
#define ellFirst(PLIST) ((PLIST)->node.next)
|
||||
/** \brief Find the last node in list
|
||||
* \param PLIST Pointer to list descriptor
|
||||
* \return Pointer to last node in the list
|
||||
*/
|
||||
#define ellLast(PLIST) ((PLIST)->node.previous)
|
||||
/** \brief Find the next node in list
|
||||
* \param PNODE Pointer to node whose successor is to be found
|
||||
* \return Pointer to the node following \c PNODE
|
||||
*/
|
||||
#define ellNext(PNODE) ((PNODE)->next)
|
||||
/** \brief Find the previous node in list
|
||||
* \param PNODE Pointer to node whose predecessor is to be found
|
||||
* \return Pointer to the node prior to \c PNODE
|
||||
*/
|
||||
#define ellPrevious(PNODE) ((PNODE)->previous)
|
||||
/** \brief Free up the list
|
||||
* \param PLIST List for which to free all nodes
|
||||
*/
|
||||
#define ellFree(PLIST) ellFree2(PLIST, free)
|
||||
|
||||
/**
|
||||
* \brief Adds a node to the end of a list
|
||||
* \param pList Pointer to list descriptor
|
||||
* \param pNode Pointer to node to be added
|
||||
*/
|
||||
epicsShareFunc void ellAdd (ELLLIST *pList, ELLNODE *pNode);
|
||||
/**
|
||||
* \brief Concatenates a list to the end of another list.
|
||||
* The list to be added is left empty. Either list (or both)
|
||||
* can be empty at the beginning of the operation.
|
||||
* \param pDstList Destination list
|
||||
* \param pAddList List to be added to \c pDstList
|
||||
*/
|
||||
epicsShareFunc void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList);
|
||||
/**
|
||||
* \brief Deletes a node from a list.
|
||||
* \param pList Pointer to list descriptor
|
||||
* \param pNode Pointer to node to be deleted
|
||||
*/
|
||||
epicsShareFunc void ellDelete (ELLLIST *pList, ELLNODE *pNode);
|
||||
/**
|
||||
* \brief Extract a sublist from a list.
|
||||
* \param pSrcList Pointer to source list
|
||||
* \param pStartNode First node in \c pSrcList to be extracted
|
||||
* \param pEndNode Last node in \c pSrcList to be extracted
|
||||
* \param pDstList Pointer to list where to put extracted list
|
||||
*/
|
||||
epicsShareFunc void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList);
|
||||
/**
|
||||
* \brief Deletes and returns the first node from a list
|
||||
* \param pList Pointer to list from which to get node
|
||||
* \return Pointer to the first node from the list, or NULL if the list is empty
|
||||
*/
|
||||
epicsShareFunc ELLNODE * ellGet (ELLLIST *pList);
|
||||
/**
|
||||
* \brief Deletes and returns the last node from a list.
|
||||
* \param pList Pointer to list from which to get node
|
||||
* \return Pointer to the last node from the list, or NULL if the list is empty
|
||||
*/
|
||||
epicsShareFunc ELLNODE * ellPop (ELLLIST *pList);
|
||||
/**
|
||||
* \brief Inserts a node into a list immediately after a specific node
|
||||
* \param plist Pointer to list into which to insert node
|
||||
* \param pPrev Pointer to the node after which to insert
|
||||
* \param pNode Pointer to the node to be inserted
|
||||
* \note If \c pPrev is NULL \c pNode will be inserted at the head of the list
|
||||
*/
|
||||
epicsShareFunc void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode);
|
||||
/**
|
||||
* \brief Find the Nth node in a list
|
||||
* \param pList Pointer to list from which to find node
|
||||
* \param nodeNum Index of the node to be found
|
||||
* \return Pointer to the element at index \c nodeNum in pList, or NULL if
|
||||
* there is no such node in the list.
|
||||
* \note The first node has index 1.
|
||||
*/
|
||||
epicsShareFunc ELLNODE * ellNth (ELLLIST *pList, int nodeNum);
|
||||
/**
|
||||
* \brief Find the list node \c nStep steps away from a specified node
|
||||
* \param pNode The known node
|
||||
* \param nStep How many steps to take, may be negative to step backwards
|
||||
* \return Pointer to the node \c nStep nodes from \c pNode, or NULL if there
|
||||
* is no such node in the list.
|
||||
*/
|
||||
epicsShareFunc ELLNODE * ellNStep (ELLNODE *pNode, int nStep);
|
||||
/**
|
||||
* \brief Find the index of a specific node in a list
|
||||
* \param pList Pointer to list to search
|
||||
* \param pNode Pointer to node to search for
|
||||
* \return The node's index, or -1 if it cannot be found on the list.
|
||||
* \note The first node has index 1.
|
||||
*/
|
||||
epicsShareFunc int ellFind (ELLLIST *pList, ELLNODE *pNode);
|
||||
|
||||
typedef int (*pListCmp)(const ELLNODE* A, const ELLNODE* B);
|
||||
epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp);
|
||||
/**
|
||||
* \brief Stable (MergeSort) of a given list.
|
||||
* \param pList Pointer to list to be sorted
|
||||
* \param pListCmp Compare function to be used
|
||||
* \note The comparison function cmp(A,B) is expected
|
||||
* to return -1 for A<B, 0 for A==B, and 1 for A>B.
|
||||
*
|
||||
* \note Use of mergesort algorithm based on analysis by
|
||||
* http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
|
||||
*/
|
||||
epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp pListCmp);
|
||||
/**
|
||||
* \brief Free all the nodes in a list.
|
||||
*
|
||||
* This routine empties a list, calling freeFunc() for every node on it.
|
||||
* \param pList List from which to free all nodes
|
||||
* \param freeFunc The free() routine to be called
|
||||
* \note The nodes in the list are free()'d on the assumption that the node
|
||||
* structures were malloc()'d one-at-a-time and that the ELLNODE structure is
|
||||
* the first member of the parent structure.
|
||||
*/
|
||||
epicsShareFunc void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc);
|
||||
/**
|
||||
* \brief Verifies that the list is consistent
|
||||
* \param pList List to be verified
|
||||
*/
|
||||
epicsShareFunc void ellVerify (ELLLIST *pList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
201
modules/libcom/src/env/envDefs.h
vendored
201
modules/libcom/src/env/envDefs.h
vendored
@@ -4,26 +4,27 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Roger A. Cole
|
||||
* Date: 07-20-91
|
||||
|
||||
/**
|
||||
* \file envDefs.h
|
||||
* \author Roger A. Cole
|
||||
*
|
||||
* \brief Routines to get and set EPICS environment parameters.
|
||||
*
|
||||
* This file defines environment parameters used by EPICS and the
|
||||
* routines used to get and set those parameter values.
|
||||
*
|
||||
* The ENV_PARAM's declared here are defined in the generated file
|
||||
* envData.c by the bldEnvData.pl Perl script, which parses this file
|
||||
* and the build system's CONFIG_ENV and CONFIG_SITE_ENV files.
|
||||
* User programs can define their own environment parameters for their
|
||||
* own use--the only caveat is that such parameters aren't automatically
|
||||
* setup by EPICS.
|
||||
*
|
||||
* \note bldEnvData.pl looks for "epicsShareExtern const ENV_PARAM <name>;"
|
||||
*/
|
||||
/****************************************************************************
|
||||
* TITLE envDefs.h - definitions for environment get/set routines
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This file defines the environment parameters for EPICS. These
|
||||
* ENV_PARAM's are created in envData.c by bldEnvData for
|
||||
* use by EPICS programs running under UNIX and VxWorks.
|
||||
*
|
||||
* User programs can define their own environment parameters for their
|
||||
* own use--the only caveat is that such parameters aren't automatically
|
||||
* setup by EPICS.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef envDefsH
|
||||
#define envDefsH
|
||||
@@ -34,14 +35,14 @@ extern "C" {
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/**
|
||||
* \brief A structure to hold a single environment parameter
|
||||
*/
|
||||
typedef struct envParam {
|
||||
char *name; /* text name of the parameter */
|
||||
char *pdflt;
|
||||
char *name; /**< \brief Name of the parameter */
|
||||
char *pdflt; /**< \brief Default value */
|
||||
} ENV_PARAM;
|
||||
|
||||
/*
|
||||
* bldEnvData.pl looks for "epicsShareExtern const ENV_PARAM <name>;"
|
||||
*/
|
||||
epicsShareExtern const ENV_PARAM EPICS_CA_ADDR_LIST;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CA_CONN_TMO;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CA_AUTO_ADDR_LIST;
|
||||
@@ -57,7 +58,7 @@ epicsShareExtern const ENV_PARAM EPICS_CAS_IGNORE_ADDR_LIST;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CAS_AUTO_BEACON_ADDR_LIST;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_ADDR_LIST;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CAS_SERVER_PORT;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CA_BEACON_PERIOD; /* deprecated */
|
||||
epicsShareExtern const ENV_PARAM EPICS_CA_BEACON_PERIOD; /**< \brief deprecated */
|
||||
epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PERIOD;
|
||||
epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PORT;
|
||||
epicsShareExtern const ENV_PARAM EPICS_BUILD_COMPILER_CLASS;
|
||||
@@ -74,30 +75,167 @@ epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_PS1;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_HISTSIZE;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
|
||||
|
||||
epicsShareExtern const ENV_PARAM *env_param_list[];
|
||||
|
||||
struct in_addr;
|
||||
|
||||
epicsShareFunc char * epicsShareAPI
|
||||
/**
|
||||
* \brief Get value of a configuration parameter
|
||||
*
|
||||
* Gets the value of a configuration parameter from the environment
|
||||
* and copies it into the caller's buffer. If the parameter isn't
|
||||
* set in the environment, the default value for the parameter is
|
||||
* copied instead. If neither provides a non-empty string the buffer
|
||||
* is set to '\0' and NULL is returned.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \param bufDim Dimension of parameter buffer
|
||||
* \param pBuf Pointer to parameter buffer
|
||||
* \return Pointer to the environment variable value string, or
|
||||
* NULL if no parameter value and default value was empty.
|
||||
*/
|
||||
epicsShareFunc char * epicsShareAPI
|
||||
envGetConfigParam(const ENV_PARAM *pParam, int bufDim, char *pBuf);
|
||||
epicsShareFunc const char * epicsShareAPI
|
||||
|
||||
/**
|
||||
* \brief Get a configuration parameter's value or default string.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \return Pointer to the environment variable value string, or to
|
||||
* the default value for the parameter, or NULL if those strings
|
||||
* were empty or not set.
|
||||
*/
|
||||
epicsShareFunc const char * epicsShareAPI
|
||||
envGetConfigParamPtr(const ENV_PARAM *pParam);
|
||||
epicsShareFunc long epicsShareAPI
|
||||
|
||||
/**
|
||||
* \brief Print the value of a configuration parameter.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \return 0
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI
|
||||
envPrtConfigParam(const ENV_PARAM *pParam);
|
||||
epicsShareFunc long epicsShareAPI
|
||||
|
||||
/**
|
||||
* \brief Get value of an inet addr config parameter.
|
||||
*
|
||||
* Gets the value of a configuration parameter and copies it into
|
||||
* the caller's (struct in_addr) buffer. If the configuration parameter
|
||||
* isn't found in the environment, the default value for that parameter
|
||||
* will be used. The resulting string is converted from a dotted-quad
|
||||
* format or looked up using the DNS and copied into the inet structure.
|
||||
*
|
||||
* If no parameter is found and there is no default, then -1 is
|
||||
* returned and the callers buffer is unmodified.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \param pAddr Pointer to struct to receive inet addr.
|
||||
* \return 0, or -1 if an error is encountered
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI
|
||||
envGetInetAddrConfigParam(const ENV_PARAM *pParam, struct in_addr *pAddr);
|
||||
epicsShareFunc long epicsShareAPI
|
||||
|
||||
/**
|
||||
* \brief Get value of a double configuration parameter.
|
||||
*
|
||||
* Gets the value of a configuration parameter, converts it into a
|
||||
* \c double value and copies that into the caller's buffer. If the
|
||||
* configuration parameter isn't found in the environment, the
|
||||
* default value for the parameter is used instead.
|
||||
*
|
||||
* If no parameter is found and there is no default, then -1 is
|
||||
* returned and the callers buffer is unmodified.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \param pDouble Pointer to place to store value.
|
||||
* \return 0, or -1 if an error is encountered
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI
|
||||
envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble);
|
||||
epicsShareFunc long epicsShareAPI
|
||||
|
||||
/**
|
||||
* \brief Get value of a long configuration parameter.
|
||||
*
|
||||
* Gets the value of a configuration parameter, converts it into a
|
||||
* \c long value and copies that into the caller's buffer. If the
|
||||
* configuration parameter isn't found in the environment, the
|
||||
* default value for the parameter is used instead.
|
||||
*
|
||||
* If no parameter is found and there is no default, then -1 is
|
||||
* returned and the callers buffer is unmodified.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \param pLong Pointer to place to store value.
|
||||
* \return 0, or -1 if an error is encountered
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI
|
||||
envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong);
|
||||
epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam
|
||||
|
||||
/**
|
||||
* \brief Get value of a port number configuration parameter.
|
||||
*
|
||||
* Returns the value of a configuration parameter that represents
|
||||
* an inet port number. If no environment variable is found the
|
||||
* default parameter value is used, and if that is also unset the
|
||||
* \c defaultPort argument returned instead. The integer value must
|
||||
* fall between the values IPPORT_USERRESERVED and USHRT_MAX or the
|
||||
* \c defaultPort argument will be substituted instead.
|
||||
*
|
||||
* \param pEnv Pointer to config param structure.
|
||||
* \param defaultPort Port number to be used if environment settings invalid.
|
||||
* \return Port number.
|
||||
*/
|
||||
epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam
|
||||
(const ENV_PARAM *pEnv, unsigned short defaultPort);
|
||||
/**
|
||||
* \brief Get value of a boolean configuration parameter.
|
||||
*
|
||||
* Gets the value of a configuration parameter, and puts the value
|
||||
* 0 or 1 into the caller's buffer depending on the value. If the
|
||||
* configuration parameter isn't found in the environment, the
|
||||
* default value for the parameter is used instead.
|
||||
*
|
||||
* A value is treated as True (1) if it compares equal to the
|
||||
* string "yes" with a case-independent string comparison. All
|
||||
* other strings are treated as False (0).
|
||||
*
|
||||
* If no parameter is found and there is no default, then -1 is
|
||||
* returned and the callers buffer is unmodified.
|
||||
*
|
||||
* \param pParam Pointer to config param structure.
|
||||
* \param pBool Pointer to place to store value.
|
||||
* \return 0, or -1 if an error is encountered
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI
|
||||
envGetBoolConfigParam(const ENV_PARAM *pParam, int *pBool);
|
||||
|
||||
/**
|
||||
* \brief Prints all configuration parameters and their current value.
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
epicsShareFunc long epicsShareAPI epicsPrtEnvParams(void);
|
||||
|
||||
/**
|
||||
* \brief Set an environment variable's value
|
||||
*
|
||||
* The setenv() routine is not available on all operating systems.
|
||||
* This routine provides a portable alternative for all EPICS targets.
|
||||
* \param name Environment variable name.
|
||||
* \param value New value for environment variable.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value);
|
||||
/**
|
||||
* \brief Clear the value of an environment variable
|
||||
* \param name Environment variable name.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEnvUnset (const char *name);
|
||||
/**
|
||||
* \brief Print value of an environment variable, or all variables
|
||||
*
|
||||
* \param name Environment variable name, or NULL to show all.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -105,4 +243,3 @@ epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name);
|
||||
#endif
|
||||
|
||||
#endif /*envDefsH*/
|
||||
|
||||
|
||||
@@ -85,27 +85,27 @@ epicsShareFunc const iocshVarDef * epicsShareAPI iocshFindVariable(
|
||||
/* This should only be called when iocsh is no longer needed*/
|
||||
epicsShareFunc void epicsShareAPI iocshFree(void);
|
||||
|
||||
/** shorthand for @code iocshLoad(pathname, NULL) @endcode */
|
||||
/** shorthand for \code iocshLoad(pathname, NULL) \endcode */
|
||||
epicsShareFunc int epicsShareAPI iocsh(const char *pathname);
|
||||
/** shorthand for @code iocshRun(cmd, NULL) @endcode */
|
||||
/** shorthand for \code iocshRun(cmd, NULL) \endcode */
|
||||
epicsShareFunc int epicsShareAPI iocshCmd(const char *cmd);
|
||||
/** Read and evaluate IOC shell commands from the given file.
|
||||
* @param pathname Path to script file
|
||||
* @param macros NULL or a comma seperated list of macro definitions. eg. "VAR1=x,VAR2=y"
|
||||
* @return 0 on success, non-zero on error
|
||||
* \param pathname Path to script file
|
||||
* \param macros NULL or a comma seperated list of macro definitions. eg. "VAR1=x,VAR2=y"
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI iocshLoad(const char *pathname, const char* macros);
|
||||
/** Evaluate a single IOC shell command
|
||||
* @param cmd Command string. eg. "echo \"something or other\""
|
||||
* @param macros NULL or a comma seperated list of macro definitions. eg. "VAR1=x,VAR2=y"
|
||||
* @return 0 on success, non-zero on error
|
||||
* \param cmd Command string. eg. "echo \"something or other\""
|
||||
* \param macros NULL or a comma seperated list of macro definitions. eg. "VAR1=x,VAR2=y"
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI iocshRun(const char *cmd, const char* macros);
|
||||
|
||||
/** @brief Signal error from an IOC shell function.
|
||||
/** \brief Signal error from an IOC shell function.
|
||||
*
|
||||
* @param err 0 - success (no op), !=0 - error
|
||||
* @return The err argument value.
|
||||
* \param err 0 - success (no op), !=0 - error
|
||||
* \return The err argument value.
|
||||
*/
|
||||
epicsShareFunc int iocshSetError(int err);
|
||||
|
||||
|
||||
@@ -4,20 +4,26 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Definitions for macro substitution library (macLib)
|
||||
/**
|
||||
* \file macLib.h
|
||||
* \brief Text macro substitution routines
|
||||
* \author William Lupton, W. M. Keck Observatory
|
||||
*
|
||||
* William Lupton, W. M. Keck Observatory
|
||||
* This general purpose macro substitution library
|
||||
* is used for all macro substitutions in EPICS Base.
|
||||
*
|
||||
* Most routines return 0 (OK) on success, -1 (ERROR) on failure,
|
||||
* or small positive values for extra info.
|
||||
* The macGetValue() and macExpandString() routines depart from this
|
||||
* and return information both on success / failure and on value length.
|
||||
* Errors and warnings are reported using errlogPrintf().
|
||||
*/
|
||||
|
||||
#ifndef INCmacLibH
|
||||
#define INCmacLibH
|
||||
|
||||
/*
|
||||
* EPICS include files needed by this file
|
||||
*/
|
||||
#include "ellLib.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
@@ -25,137 +31,275 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum size of macro name or value string (simpler to make fixed)
|
||||
/** \brief Maximum size of a macro name or value
|
||||
*/
|
||||
#define MAC_SIZE 256
|
||||
|
||||
/*
|
||||
* Macro substitution context. One of these contexts is allocated each time
|
||||
* macCreateHandle() is called
|
||||
/** \brief Macro substitution context, for use by macLib routines only.
|
||||
*
|
||||
* An application may have multiple active contexts if desired.
|
||||
*/
|
||||
typedef struct {
|
||||
long magic; /* magic number (used for authentication) */
|
||||
int dirty; /* values need expanding from raw values? */
|
||||
int level; /* scoping level */
|
||||
int debug; /* debugging level */
|
||||
ELLLIST list; /* macro name / value list */
|
||||
int flags; /* operating mode flags */
|
||||
long magic; /**< \brief magic number (used for authentication) */
|
||||
int dirty; /**< \brief values need expanding from raw values? */
|
||||
int level; /**< \brief scoping level */
|
||||
int debug; /**< \brief debugging level */
|
||||
ELLLIST list; /**< \brief macro name / value list */
|
||||
int flags; /**< \brief operating mode flags */
|
||||
} MAC_HANDLE;
|
||||
|
||||
/*
|
||||
* Function prototypes (core library)
|
||||
/** \name Core Library
|
||||
* The core library provides a minimal set of basic operations.
|
||||
* @{
|
||||
*/
|
||||
epicsShareFunc long /* 0 = OK; <0 = ERROR */
|
||||
|
||||
/**
|
||||
* \brief Creates a new macro substitution context.
|
||||
* \return 0 = OK; <0 = ERROR
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macCreateHandle(
|
||||
MAC_HANDLE **handle, /* address of variable to receive pointer */
|
||||
/* to new macro substitution context */
|
||||
MAC_HANDLE **handle, /**< pointer to variable to receive pointer
|
||||
to new macro substitution context */
|
||||
|
||||
const char * pairs[] /* pointer to NULL-terminated array of */
|
||||
/* {name,value} pair strings; a NULL */
|
||||
/* value implies undefined; a NULL */
|
||||
/* argument implies no macros */
|
||||
const char * pairs[] /**< pointer to NULL-terminated array of
|
||||
{name,value} pair strings. A NULL
|
||||
value implies undefined; a NULL \c pairs
|
||||
argument implies no macros. */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Disable or enable warning messages.
|
||||
*
|
||||
* The macExpandString() routine prints warnings when it cant expand a macro.
|
||||
* This routine can be used to silence those warnings. A non zero value will
|
||||
* suppress the warning messages from subsequent library routines given the
|
||||
* same \c handle.
|
||||
*/
|
||||
epicsShareFunc void
|
||||
epicsShareAPI macSuppressWarning(
|
||||
MAC_HANDLE *handle, /* opaque handle */
|
||||
MAC_HANDLE *handle, /**< opaque handle */
|
||||
|
||||
int falseTrue /*0 means issue, 1 means suppress*/
|
||||
int falseTrue /**< 0 means issue, 1 means suppress*/
|
||||
);
|
||||
|
||||
epicsShareFunc long /* strlen(dest), <0 if any macros are */
|
||||
/* undefined */
|
||||
epicsShareAPI macExpandString(
|
||||
MAC_HANDLE *handle, /* opaque handle */
|
||||
|
||||
const char *src, /* source string */
|
||||
|
||||
char *dest, /* destination string */
|
||||
|
||||
long capacity /* capacity of destination buffer (dest) */
|
||||
);
|
||||
|
||||
|
||||
epicsShareFunc long /* strlen(value) */
|
||||
epicsShareAPI macPutValue(
|
||||
MAC_HANDLE *handle, /* opaque handle */
|
||||
|
||||
const char *name, /* macro name */
|
||||
|
||||
const char *value /* macro value */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* strlen(value), <0 if undefined */
|
||||
epicsShareAPI macGetValue(
|
||||
MAC_HANDLE *handle, /* opaque handle */
|
||||
|
||||
const char *name, /* macro name or reference */
|
||||
|
||||
char *value, /* string to receive macro value or name */
|
||||
/* argument if macro is undefined */
|
||||
|
||||
long capacity /* capacity of destination buffer (value) */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* 0 = OK; <0 = ERROR */
|
||||
epicsShareAPI macDeleteHandle(
|
||||
MAC_HANDLE *handle /* opaque handle */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* 0 = OK; <0 = ERROR */
|
||||
epicsShareAPI macPushScope(
|
||||
MAC_HANDLE *handle /* opaque handle */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* 0 = OK; <0 = ERROR */
|
||||
epicsShareAPI macPopScope(
|
||||
MAC_HANDLE *handle /* opaque handle */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* 0 = OK; <0 = ERROR */
|
||||
epicsShareAPI macReportMacros(
|
||||
MAC_HANDLE *handle /* opaque handle */
|
||||
);
|
||||
|
||||
/*
|
||||
* Function prototypes (utility library)
|
||||
/**
|
||||
* \brief Expand a string which may contain macro references.
|
||||
* \return Returns the length of the expanded string, <0 if any macro are
|
||||
* undefined
|
||||
*
|
||||
* This routine parses the \c src string looking for macro references and
|
||||
* passes any it finds to macGetValue() for translation.
|
||||
*
|
||||
* \note The return value is similar to that of macGetValue(). Its absolute
|
||||
* value is the number of characters copied to \c dest. If the return value
|
||||
* is negative, at least one undefined macro was left unexpanded.
|
||||
*/
|
||||
epicsShareFunc long /* #defns encountered; <0 = ERROR */
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macExpandString(
|
||||
MAC_HANDLE *handle, /**< opaque handle */
|
||||
|
||||
const char *src, /**< source string */
|
||||
|
||||
char *dest, /**< destination string */
|
||||
|
||||
long capacity /**< capacity of destination buffer (dest) */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Sets the value of a specific macro.
|
||||
* \return Returns the length of the value string.
|
||||
* \note If \c value is NULL, all instances of \c name are undefined at
|
||||
* all scoping levels (the named macro doesn't have to exist in this case).
|
||||
* Macros referenced in \c value need not be defined at this point.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macPutValue(
|
||||
MAC_HANDLE *handle, /**< opaque handle */
|
||||
|
||||
const char *name, /**< macro name */
|
||||
|
||||
const char *value /**< macro value */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Returns the value of a macro
|
||||
* \return Returns the length of the value string, <0 if undefined
|
||||
*
|
||||
* \c value will be zero-terminated if the length of the value is less than
|
||||
* \c capacity. The return value is the number of characters copied to
|
||||
* \c value (see below for behavior if the macro is undefined). If \c capacity
|
||||
* is zero, no characters will be copied to \c value (which may be NULL)
|
||||
* and the call can be used to check whether the macro is defined.
|
||||
*
|
||||
* \note Truncation of the value is not reported, applications should assume
|
||||
* that truncation has occurred if the return value is equal to capacity.
|
||||
*
|
||||
* If the macro is undefined, the macro reference will be returned in
|
||||
* the value string (if permitted by maxlen) and the function value will
|
||||
* be _minus_ the number of characters copied. Note that treatment of
|
||||
* \c capacity is intended to be consistent with the strncpy() routine.
|
||||
*
|
||||
* If the value contains macro references, these references will be
|
||||
* expanded recursively. This expansion will detect a direct or indirect
|
||||
* self reference.
|
||||
*
|
||||
* Macro references begin with a "$" immediately followed by either a
|
||||
* "(" or a "{" character. The macro name comes next, and may optionally
|
||||
* be succeeded by an "=" and a default value, which will be returned if
|
||||
* the named macro is undefined at the moment of expansion. A reference
|
||||
* is terminated by the matching ")" or "}" character.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macGetValue(
|
||||
MAC_HANDLE *handle, /**< opaque handle */
|
||||
|
||||
const char *name, /**< macro name or reference */
|
||||
|
||||
char *value, /**< string to receive macro value or name
|
||||
argument if macro is undefined */
|
||||
|
||||
long capacity /**< capacity of destination buffer (value) */
|
||||
);
|
||||
/**
|
||||
* \brief Marks a handle invalid, and frees all storage associated with it
|
||||
* \return 0 = OK; <0 = ERROR
|
||||
* \note Note that this does not free any strings into which macro values have
|
||||
* been returned. Macro values are always returned into strings which
|
||||
* were pre-allocated by the caller.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macDeleteHandle(
|
||||
MAC_HANDLE *handle /**< opaque handle */
|
||||
);
|
||||
/**
|
||||
* \brief Marks the start of a new scoping level
|
||||
* \return 0 = OK; <0 = ERROR
|
||||
*
|
||||
* Marks all macro definitions added after this call as belonging
|
||||
* to another scope. These macros will be lost on a macPopScope()
|
||||
* call and those at the current scope will be re-instated.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macPushScope(
|
||||
MAC_HANDLE *handle /**< opaque handle */
|
||||
);
|
||||
/**
|
||||
* \brief Retrieve the last pushed scope (like stack operations)
|
||||
* \return 0 = OK; <0 = ERROR
|
||||
*
|
||||
* See macPushScope()
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macPopScope(
|
||||
MAC_HANDLE *handle /**< opaque handle */
|
||||
);
|
||||
/**
|
||||
* \brief Reports details of current definitions
|
||||
* \return 0 = OK; <0 = ERROR
|
||||
* This sends details of current definitions to standard output,
|
||||
* and is intended purely for debugging purposes.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macReportMacros(
|
||||
MAC_HANDLE *handle /**< opaque handle */
|
||||
);
|
||||
/** @} */
|
||||
|
||||
/** \name Utility Library
|
||||
* These convenience functions are intended for applications to use and
|
||||
* provide a more convenient interface for some purposes.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Parse macro definitions into an array of {name, value} pairs.
|
||||
* \return Number of macros found; <0 = ERROR
|
||||
*
|
||||
* This takes a set of macro definitions in "a=xxx,b=yyy" format and
|
||||
* converts them into an array of pointers to character strings which
|
||||
* are, in order, "first name", "first value", "second name", "second
|
||||
* value" etc. The array is terminated with two NULL pointers and all
|
||||
* storage is allocated contiguously so that it can be freed with a
|
||||
* single call to free().
|
||||
*
|
||||
* This routine is independent of any handle and provides a generally
|
||||
* useful service which may be used elsewhere. Any macro references in
|
||||
* values are not expanded at this point since the referenced macros may
|
||||
* be defined or redefined before the macro actually has to be
|
||||
* translated.
|
||||
*
|
||||
* Shell-style escapes and quotes are supported, as are things like
|
||||
* "A=B,B=$(C$(A)),CA=CA,CB=CB" (sets B to "CB"). White space is
|
||||
* significant within values but ignored elsewhere (i.e. surrounding "="
|
||||
* and "," characters).
|
||||
*
|
||||
* The function returns the number of definitions encountered, or -1 if
|
||||
* the supplied string is invalid.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macParseDefns(
|
||||
MAC_HANDLE *handle, /* opaque handle; can be NULL if default */
|
||||
/* special characters are to be used */
|
||||
MAC_HANDLE *handle, /**< opaque handle; may be NULL if debug
|
||||
messages are not required. */
|
||||
|
||||
const char *defns, /* macro definitions in "a=xxx,b=yyy" */
|
||||
/* format */
|
||||
const char *defns, /**< macro definitions in "a=xxx,b=yyy"
|
||||
format */
|
||||
|
||||
char **pairs[] /* address of variable to receive pointer */
|
||||
/* to NULL-terminated array of {name, */
|
||||
/* value} pair strings; all storage is */
|
||||
/* allocated contiguously */
|
||||
char **pairs[] /**< address of variable to receive pointer
|
||||
to NULL-terminated array of {name,
|
||||
value} pair strings; all storage is
|
||||
allocated contiguously */
|
||||
);
|
||||
|
||||
epicsShareFunc long /* #macros defined; <0 = ERROR */
|
||||
/**
|
||||
* \brief Install set of {name, value} pairs as definitions
|
||||
* \return Number of macros defined; <0 = ERROR
|
||||
*
|
||||
* This takes an array of pairs as defined above and installs them as
|
||||
* definitions by calling macPutValue(). The pairs array is terminated
|
||||
* by a NULL pointer.
|
||||
*/
|
||||
epicsShareFunc long
|
||||
epicsShareAPI macInstallMacros(
|
||||
MAC_HANDLE *handle, /* opaque handle */
|
||||
MAC_HANDLE *handle, /**< opaque handle */
|
||||
|
||||
char *pairs[] /* pointer to NULL-terminated array of */
|
||||
/* {name,value} pair strings; a NULL */
|
||||
/* value implies undefined; a NULL */
|
||||
/* argument implies no macros */
|
||||
char *pairs[] /**< pointer to NULL-terminated array of
|
||||
{name,value} pair strings; a NULL
|
||||
value implies undefined; a NULL
|
||||
argument implies no macros */
|
||||
);
|
||||
|
||||
epicsShareFunc char * /* expanded string; NULL if any undefined macros */
|
||||
/**
|
||||
* \brief Expand environment variables in a string.
|
||||
* \return Expanded string; NULL if any undefined macros were used.
|
||||
*
|
||||
* This routine expands a string which may contain macros that are
|
||||
* environment variables. It parses the string looking for such
|
||||
* references and passes them to macGetValue() for translation. It uses
|
||||
* malloc() to allocate space for the expanded string and returns a
|
||||
* pointer to this null-terminated string. It returns NULL if the source
|
||||
* string contains any undefined references.
|
||||
*/
|
||||
epicsShareFunc char *
|
||||
epicsShareAPI macEnvExpand(
|
||||
const char *str /* string to be expanded */
|
||||
const char *str /**< string to be expanded */
|
||||
);
|
||||
|
||||
epicsShareFunc char * /* expanded string; NULL if any undefined macros */
|
||||
/**
|
||||
* \brief Expands macros and environment variables in a string.
|
||||
* \return Expanded string; NULL if any undefined macros were used.
|
||||
*
|
||||
* This routine is similar to macEnvExpand() but allows an optional handle
|
||||
* to be passed in that may contain additional macro definitions.
|
||||
* These macros are appended to the set of macros from environment
|
||||
* variables when expanding the string.
|
||||
*/
|
||||
epicsShareFunc char *
|
||||
epicsShareAPI macDefExpand(
|
||||
const char *str, /* string to be expanded */
|
||||
MAC_HANDLE *macros /* opaque handle; can be NULL if default */
|
||||
/* special characters are to be used */
|
||||
const char *str, /**< string to be expanded */
|
||||
MAC_HANDLE *macros /**< opaque handle; may be NULL if only
|
||||
environment variables are to be used */
|
||||
);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -5,9 +5,15 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* src/libCom/adjustment.h */
|
||||
|
||||
/**
|
||||
* \file adjustment.h
|
||||
* \brief Declare function `adjustToWorstCaseAlignment`
|
||||
*
|
||||
* Declares a single function `adjustToWorstCaseAlignment`.
|
||||
*/
|
||||
|
||||
#ifndef INCadjustmenth
|
||||
#define INCadjustmenth
|
||||
@@ -17,6 +23,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** returns a value larger or equal than `size`, that is an exact
|
||||
multiple of the worst case alignment for the architecture on
|
||||
which the routine is executed. */
|
||||
epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -25,4 +34,3 @@ epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size);
|
||||
|
||||
|
||||
#endif /*INCadjustmenth*/
|
||||
|
||||
|
||||
@@ -4,13 +4,17 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Alarm definitions, must match menuAlarmSevr.dbd and menuAlarmStat.dbd */
|
||||
|
||||
/*
|
||||
* Authors: Bob Dalesio and Marty Kraimer
|
||||
* Date: 11-7-90
|
||||
/**
|
||||
* \file alarm.h
|
||||
* \brief Alarm severity and status/condition values
|
||||
* \author Bob Dalesio and Marty Kraimer
|
||||
*
|
||||
* These alarm definitions must match the related
|
||||
* menuAlarmSevr.dbd and menuAlarmStat.dbd files
|
||||
* found in the IOC database module.
|
||||
*/
|
||||
|
||||
#ifndef INC_alarm_H
|
||||
@@ -22,54 +26,68 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief The NO_ALARM value can be used as both a severity and a status.
|
||||
*/
|
||||
#define NO_ALARM 0
|
||||
|
||||
/* ALARM SEVERITIES - must match menuAlarmSevr.dbd */
|
||||
|
||||
/**
|
||||
* \brief Alarm severity values
|
||||
* \note These must match the choices in menuAlarmSevr.dbd
|
||||
*/
|
||||
typedef enum {
|
||||
epicsSevNone = NO_ALARM,
|
||||
epicsSevMinor,
|
||||
epicsSevMajor,
|
||||
epicsSevInvalid,
|
||||
ALARM_NSEV
|
||||
epicsSevNone = NO_ALARM, /**< No alarm */
|
||||
epicsSevMinor, /**< Minor alarm severity */
|
||||
epicsSevMajor, /**< Major alarm severity */
|
||||
epicsSevInvalid, /**< Invalid alarm severity */
|
||||
ALARM_NSEV /**< Number of alarm severities */
|
||||
} epicsAlarmSeverity;
|
||||
|
||||
/**
|
||||
* \name Original macros for alarm severity values
|
||||
* @{
|
||||
*/
|
||||
#define firstEpicsAlarmSev epicsSevNone
|
||||
#define MINOR_ALARM epicsSevMinor
|
||||
#define MAJOR_ALARM epicsSevMajor
|
||||
#define INVALID_ALARM epicsSevInvalid
|
||||
#define lastEpicsAlarmSev epicsSevInvalid
|
||||
/** @} */
|
||||
|
||||
|
||||
/* ALARM STATUS - must match menuAlarmStat.dbd */
|
||||
|
||||
/**
|
||||
* \brief Alarm status/condition values
|
||||
* \note These must match the choices in menuAlarmStat.dbd
|
||||
*/
|
||||
typedef enum {
|
||||
epicsAlarmNone = NO_ALARM,
|
||||
epicsAlarmRead,
|
||||
epicsAlarmWrite,
|
||||
epicsAlarmHiHi,
|
||||
epicsAlarmHigh,
|
||||
epicsAlarmLoLo,
|
||||
epicsAlarmLow,
|
||||
epicsAlarmState,
|
||||
epicsAlarmCos,
|
||||
epicsAlarmComm,
|
||||
epicsAlarmTimeout,
|
||||
epicsAlarmHwLimit,
|
||||
epicsAlarmCalc,
|
||||
epicsAlarmScan,
|
||||
epicsAlarmLink,
|
||||
epicsAlarmSoft,
|
||||
epicsAlarmBadSub,
|
||||
epicsAlarmUDF,
|
||||
epicsAlarmDisable,
|
||||
epicsAlarmSimm,
|
||||
epicsAlarmReadAccess,
|
||||
epicsAlarmWriteAccess,
|
||||
ALARM_NSTATUS
|
||||
epicsAlarmNone = NO_ALARM, /**< No alarm */
|
||||
epicsAlarmRead, /**< Read alarm (read error) */
|
||||
epicsAlarmWrite, /**< Write alarm (write error) */
|
||||
epicsAlarmHiHi, /**< High high limit alarm */
|
||||
epicsAlarmHigh, /**< High limit alarm */
|
||||
epicsAlarmLoLo, /**< Low low limit alarm */
|
||||
epicsAlarmLow, /**< Low limit alarm */
|
||||
epicsAlarmState, /**< State alarm (e.g. off/on) */
|
||||
epicsAlarmCos, /**< Change of state alarm */
|
||||
epicsAlarmComm, /**< Communication alarm */
|
||||
epicsAlarmTimeout, /**< Timeout alarm */
|
||||
epicsAlarmHwLimit, /**< Hardware limit alarm */
|
||||
epicsAlarmCalc, /**< Calculation expression error */
|
||||
epicsAlarmScan, /**< Scan alarm, e.g. record not processed (10 times) or not in desired scan list */
|
||||
epicsAlarmLink, /**< Link alarm */
|
||||
epicsAlarmSoft, /**< Soft alarm, e.g. in sub record if subroutine gives error */
|
||||
epicsAlarmBadSub, /**< Bad subroutine alarm, e.g. in sub record subroutine not defined */
|
||||
epicsAlarmUDF, /**< Undefined value alarm, e.g. record never processed */
|
||||
epicsAlarmDisable, /**< Record disabled using DISV/DISA fields */
|
||||
epicsAlarmSimm, /**< Record is in simulation mode */
|
||||
epicsAlarmReadAccess, /**< Read access permission problem */
|
||||
epicsAlarmWriteAccess, /**< Write access permission problem */
|
||||
ALARM_NSTATUS /**< Number of alarm conditions */
|
||||
} epicsAlarmCondition;
|
||||
|
||||
/**
|
||||
* \name Original macros for alarm status/condition values
|
||||
* @{
|
||||
*/
|
||||
#define firstEpicsAlarmCond epicsAlarmNone
|
||||
#define READ_ALARM epicsAlarmRead
|
||||
#define WRITE_ALARM epicsAlarmWrite
|
||||
@@ -93,11 +111,15 @@ typedef enum {
|
||||
#define READ_ACCESS_ALARM epicsAlarmReadAccess
|
||||
#define WRITE_ACCESS_ALARM epicsAlarmWriteAccess
|
||||
#define lastEpicsAlarmCond epicsAlarmWriteAccess
|
||||
/** @} */
|
||||
|
||||
|
||||
/* Name string arrays */
|
||||
|
||||
/**
|
||||
* \brief How to convert an alarm severity into a string
|
||||
*/
|
||||
epicsShareExtern const char *epicsAlarmSeverityStrings [ALARM_NSEV];
|
||||
/**
|
||||
* \brief How to convert an alarm condition/status into a string
|
||||
*/
|
||||
epicsShareExtern const char *epicsAlarmConditionStrings [ALARM_NSTATUS];
|
||||
|
||||
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is deprecated, use alarm.h instead.
|
||||
/**
|
||||
* \file alarmString.h
|
||||
* \brief Deprecated, use alarm.h instead
|
||||
*
|
||||
* Old string names for alarm status and severity values
|
||||
* How to convert alarm status and severity values into a string for printing.
|
||||
*
|
||||
* \note This file is deprecated, use alarm.h instead.
|
||||
*/
|
||||
|
||||
#ifndef INC_alarmString_H
|
||||
@@ -22,9 +25,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Old versions of alarmString.h defined these names: */
|
||||
|
||||
/**
|
||||
* \brief An alias for epicsAlarmSeverityStrings
|
||||
*/
|
||||
#define alarmSeverityString epicsAlarmSeverityStrings
|
||||
/**
|
||||
* \brief An alias for epicsAlarmConditionStrings
|
||||
*/
|
||||
#define alarmStatusString epicsAlarmConditionStrings
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,23 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**
|
||||
* \file cantProceed.h
|
||||
* \brief Routines for code that can't continue or return after an error.
|
||||
*
|
||||
* This is the EPICS equivalent of a Kernel Panic, except that the effect
|
||||
* is to halt only the thread that detects the error.
|
||||
*/
|
||||
|
||||
/* callocMustSucceed() and mallocMustSucceed() can be
|
||||
* used in place of calloc() and malloc(). If size or count are zero, or the
|
||||
* memory allocation fails, they output a message and call cantProceed().
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCcantProceedh
|
||||
#define INCcantProceedh
|
||||
|
||||
@@ -18,9 +33,42 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
epicsShareFunc void cantProceed(const char *errorMessage, ...) EPICS_PRINTF_STYLE(1,2);
|
||||
epicsShareFunc void * callocMustSucceed(size_t count, size_t size, const char *errorMessage);
|
||||
/** \brief Suspend this thread, the caller cannot continue or return.
|
||||
*
|
||||
* The effect of calling this is to print the error message followed by
|
||||
* the name of the thread that is being suspended. A stack trace will
|
||||
* also be shown if supported by the OS, and the thread is suspended
|
||||
* inside an infinite loop.
|
||||
* \param errorMessage A printf-style error message describing the error.
|
||||
* \param ... Any parameters required for the error message.
|
||||
*/
|
||||
epicsShareFunc void cantProceed(const char *errorMessage, ...)
|
||||
EPICS_PRINTF_STYLE(1,2);
|
||||
|
||||
/** \name Memory Allocation Functions
|
||||
* These versions of calloc() and malloc() never fail, they suspend the
|
||||
* thread if the OS is unable to allocate the requested memory at the current
|
||||
* time. If the thread is resumed, they will re-try the memory allocation,
|
||||
* and will only return after it succeeds. These routines should only be used
|
||||
* while an IOC is starting up; code that runs after iocInit() should fail
|
||||
* gracefully when memory runs out.
|
||||
*/
|
||||
/** @{ */
|
||||
/** \brief A calloc() that never returns NULL.
|
||||
* \param count Number of objects.
|
||||
* \param size Size of each object.
|
||||
* \param errorMessage What this memory is needed for.
|
||||
* \return Pointer to zeroed allocated memory.
|
||||
*/
|
||||
epicsShareFunc void * callocMustSucceed(size_t count, size_t size,
|
||||
const char *errorMessage);
|
||||
/** \brief A malloc() that never returns NULL.
|
||||
* \param size Size of block to allocate.
|
||||
* \param errorMessage What this memory is needed for.
|
||||
* \return Pointer to allocated memory.
|
||||
*/
|
||||
epicsShareFunc void * mallocMustSucceed(size_t size, const char *errorMessage);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -4,11 +4,16 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
|
||||
/**
|
||||
* \file dbDefs.h
|
||||
* \author Marty Kraimer
|
||||
*
|
||||
* \brief Miscellaneous macro definitions.
|
||||
*
|
||||
* This file defines several miscellaneous macros.
|
||||
*/
|
||||
|
||||
#ifndef INC_dbDefs_H
|
||||
@@ -26,22 +31,31 @@
|
||||
#endif
|
||||
#define FALSE 0
|
||||
|
||||
/* deprecated, use static */
|
||||
/** \brief Deprecated synonym for \c static */
|
||||
#ifndef LOCAL
|
||||
# define LOCAL static
|
||||
#endif
|
||||
|
||||
/* number of elements in an array */
|
||||
/** \brief Number of elements in array */
|
||||
#ifndef NELEMENTS
|
||||
# define NELEMENTS(array) (sizeof (array) / sizeof ((array) [0]))
|
||||
#endif
|
||||
|
||||
/* byte offset of member in structure - deprecated, use offsetof */
|
||||
/** \brief Deprecated synonym for \c offsetof */
|
||||
#ifndef OFFSET
|
||||
# define OFFSET(structure, member) offsetof(structure, member)
|
||||
#endif
|
||||
|
||||
/* Subtract member byte offset, returning pointer to parent object */
|
||||
/** \brief Find parent object from a member pointer
|
||||
*
|
||||
* Subtracts the byte offset of the member in the structure from the
|
||||
* pointer to the member itself, giving a pointer to parent strucure.
|
||||
* \param ptr Pointer to a member data field of a structure
|
||||
* \param structure Type name of the parent structure
|
||||
* \param member Field name of the data member
|
||||
* \return Pointer to the parent structure
|
||||
* \note Both GCC and Clang will type-check this macro.
|
||||
*/
|
||||
#ifndef CONTAINER
|
||||
# ifdef __GNUC__
|
||||
# define CONTAINER(ptr, structure, member) ({ \
|
||||
@@ -54,15 +68,18 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*Process Variable Name Size */
|
||||
/* PVNAME_STRINGSZ includes the nil terminator */
|
||||
/** \brief Size of a record name including the nil terminator */
|
||||
#define PVNAME_STRINGSZ 61
|
||||
/** \brief Size of a record name without the nil terminator */
|
||||
#define PVNAME_SZ (PVNAME_STRINGSZ - 1)
|
||||
|
||||
/* Buffer size for the string representation of a DBF_*LINK field */
|
||||
/**
|
||||
* \def PVLINK_STRINGSZ
|
||||
* \brief Buffer size for the string representation of a DBF_*LINK field
|
||||
*/
|
||||
#define PVLINK_STRINGSZ 1024
|
||||
|
||||
/* dbAccess enums/menus can have up to this many choices */
|
||||
/** \brief dbAccess enums/menus can have up to this many choices */
|
||||
#define DB_MAX_CHOICES 30
|
||||
|
||||
#endif /* INC_dbDefs_H */
|
||||
|
||||
@@ -7,6 +7,18 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*epicsExit.h*/
|
||||
/**
|
||||
* \file epicsExit.h
|
||||
*
|
||||
* \brief Extended replacement for the Posix exit and atexit routines.
|
||||
*
|
||||
* This is an extended replacement for the Posix exit and atexit routines, which
|
||||
* also provides a pointer argument to pass to the exit handlers. This facility
|
||||
* was created because of problems on vxWorks and windows with the implementation
|
||||
* of atexit, i.e. neither of these systems implement exit and atexit according
|
||||
* to the POSIX standard.
|
||||
*/
|
||||
|
||||
#ifndef epicsExith
|
||||
#define epicsExith
|
||||
#include <shareLib.h>
|
||||
@@ -15,15 +27,63 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Pointer to a callback function that is to be called
|
||||
* by the epicsExit subsystem.
|
||||
*/
|
||||
typedef void (*epicsExitFunc)(void *arg);
|
||||
|
||||
/**
|
||||
* \brief Calls epicsExitCallAtExits(), then the OS exit() routine.
|
||||
* \param status Passed to exit()
|
||||
*/
|
||||
epicsShareFunc void epicsExit(int status);
|
||||
/**
|
||||
* \brief Arrange to call epicsExit() later from a low priority thread.
|
||||
*
|
||||
* This delays the actual call to exit() so it doesn't run in this thread.
|
||||
* \param status Passed to exit()
|
||||
*/
|
||||
epicsShareFunc void epicsExitLater(int status);
|
||||
/**
|
||||
* \brief Internal routine that runs the registered exit routines.
|
||||
*
|
||||
* Calls each of the functions registered by prior calls to epicsAtExit
|
||||
* in reverse order of their registration.
|
||||
* \note Most applications will not call this routine directly.
|
||||
*/
|
||||
epicsShareFunc void epicsExitCallAtExits(void);
|
||||
/**
|
||||
* \brief Register a function and an associated context parameter
|
||||
* \param func Function to be called when epicsExitCallAtExits is invoked.
|
||||
* \param arg Context parameter for the function.
|
||||
* \param name Function name
|
||||
*/
|
||||
epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name);
|
||||
#define epicsAtExit(F,A) epicsAtExit3(F,A,#F)
|
||||
|
||||
/**
|
||||
* \brief Convenience macro to register a function and context value to be
|
||||
* run when the process exits.
|
||||
* \param F Function to be called at process shutdown.
|
||||
* \param A Context parameter for the function.
|
||||
*/
|
||||
#define epicsAtExit(F,A) epicsAtExit3(F,A,#F)
|
||||
/**
|
||||
* \brief Internal routine that runs the registered thread exit routines.
|
||||
*
|
||||
* Calls each of the functions that were registered in the current thread by
|
||||
* calling epicsAtThreadExit(), in reverse order of their registration.
|
||||
* \note This routine is called automatically when an epicsThread's main
|
||||
* entry routine returns. It will not be run if the thread gets stopped by
|
||||
* some other method.
|
||||
*/
|
||||
epicsShareFunc void epicsExitCallAtThreadExits(void);
|
||||
/**
|
||||
* \brief Register a function and an context value to be run by this thread
|
||||
* when it returns from its entry routine.
|
||||
* \param func Function be called at thread completion.
|
||||
* \param arg Context parameter for the function.
|
||||
*/
|
||||
epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg);
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/*epicsExport.h */
|
||||
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
@@ -7,37 +5,122 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
#ifndef INCepicsExporth
|
||||
#define INCepicsExporth
|
||||
|
||||
#ifndef INC_epicsExport_H
|
||||
#define INC_epicsExport_H
|
||||
|
||||
/** \file epicsExport.h
|
||||
* \brief Exporting IOC objects.
|
||||
*
|
||||
* This header is unique, as it defines epicsExportSharedSymbols and thus
|
||||
* triggers a transition between importing declarations from other libraries,
|
||||
* to exporting symbols from our own library. The comments in shareLib.h
|
||||
* provide more information.
|
||||
*
|
||||
* This header should be included with a trailing comment to make it stand
|
||||
* out from other includes, something like this:
|
||||
\code
|
||||
#include <epicsExport.h> // defines epicsExportSharedSymbols
|
||||
\endcode
|
||||
*/
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <shareLib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <shareLib.h>
|
||||
|
||||
typedef void (*REGISTRAR)(void);
|
||||
|
||||
#define EPICS_EXPORT_POBJ(typ,obj) pvar_ ## typ ## _ ## obj
|
||||
#define EPICS_EXPORT_PFUNC(obj) pvar_func_ ## obj
|
||||
/** \brief Generate a name for an export object.
|
||||
* \param typ Object's data type.
|
||||
* \param obj Object's name.
|
||||
* \return C identifier for the export object.
|
||||
*/
|
||||
#define EPICS_EXPORT_POBJ(typ, obj) pvar_ ## typ ## _ ## obj
|
||||
|
||||
#define epicsExportAddress(typ,obj) \
|
||||
epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \
|
||||
epicsShareDef typ *EPICS_EXPORT_POBJ(typ,obj) = (typ *)(char *)&obj
|
||||
/** \brief Generate a name for an export function object.
|
||||
* \param fun Function's name.
|
||||
* \return C identifier for the export object.
|
||||
*/
|
||||
#define EPICS_EXPORT_PFUNC(fun) EPICS_EXPORT_POBJ(func, fun)
|
||||
|
||||
#define epicsExportRegistrar(func) \
|
||||
epicsShareFunc REGISTRAR EPICS_EXPORT_PFUNC(func) = (REGISTRAR)(void*)&func
|
||||
/** \brief Declare an object for exporting.
|
||||
*
|
||||
* The epicsExportAddress() macro must be used to declare any IOC object
|
||||
* that is also named in a DBD file. For example a record support source
|
||||
* file must contain a statement like:
|
||||
\code
|
||||
epicsExportAddress(rset, myRSET);
|
||||
\endcode
|
||||
*
|
||||
* A device support source file must contain a statement like:
|
||||
\code
|
||||
epicsExportAddress(dset, devMyName);
|
||||
\endcode
|
||||
* Note that the \p typ parameter for a device support entry table must be
|
||||
* spelled \c dset even if the \p obj was actually declared as some other
|
||||
* type, say using \c typed_dset .
|
||||
*
|
||||
* A driver support source file must contain a statement like:
|
||||
\code
|
||||
epicsExportAddress(drvet, drvName);
|
||||
\endcode
|
||||
*
|
||||
* A variable named in a DBD \c variable statement must be declared with:
|
||||
\code
|
||||
int myDebug = 0;
|
||||
epicsExportAddress(int, myDebug);
|
||||
\endcode
|
||||
* Only \c int and \c double are currently supported for DBD variables.
|
||||
*
|
||||
* \param typ Object's data type.
|
||||
* \param obj Object's name.
|
||||
*/
|
||||
#define epicsExportAddress(typ, obj) \
|
||||
epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \
|
||||
epicsShareDef typ *EPICS_EXPORT_POBJ(typ, obj) = (typ *) (char *) &obj
|
||||
|
||||
#define epicsRegisterFunction(func) \
|
||||
static void register_func_ ## func(void) { \
|
||||
registryFunctionAdd(#func,(REGISTRYFUNCTION)func);} \
|
||||
epicsExportRegistrar(register_func_ ## func)
|
||||
/** \brief Declare a registrar function for exporting.
|
||||
*
|
||||
* The epicsExportRegistrar() macro must be used to declare a registrar
|
||||
* function that is named in a DBD \c registrar statement. For example:
|
||||
\code
|
||||
static void myRegistrar(void) {
|
||||
...
|
||||
}
|
||||
epicsExportRegistrar(myRegistrar);
|
||||
\endcode
|
||||
*
|
||||
* \param fun Registrar function's name.
|
||||
*/
|
||||
#define epicsExportRegistrar(fun) \
|
||||
epicsShareFunc REGISTRAR EPICS_EXPORT_PFUNC(fun) = (REGISTRAR) &fun
|
||||
|
||||
/** \brief Declare and register a function for exporting.
|
||||
*
|
||||
* The epicsRegisterFunction() macro must be used to declare and register
|
||||
* a function that is named in a DBD \c function statement and called by
|
||||
* one or more subroutine or aSub records. For example:
|
||||
\code
|
||||
epicsRegisterFunction(mySubInit);
|
||||
epicsRegisterFunction(mySubProcess);
|
||||
\endcode
|
||||
*
|
||||
* \param fun Function's name
|
||||
*/
|
||||
#define epicsRegisterFunction(fun) \
|
||||
static void register_func_ ## fun(void) \
|
||||
{ \
|
||||
registryFunctionAdd(#fun, (REGISTRYFUNCTION) fun); \
|
||||
} \
|
||||
epicsExportRegistrar(register_func_ ## fun)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* epicsExporth */
|
||||
#endif /* INC_epicsExport_H */
|
||||
|
||||
@@ -5,8 +5,142 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Andrew Johnson
|
||||
/**
|
||||
* \file epicsUnitTest.h
|
||||
* \brief Unit test routines
|
||||
* \author Andrew Johnson
|
||||
*
|
||||
* The unit test routines make it easy for a test program to generate output
|
||||
* that is compatible with the Test Anything Protocol and can thus be used with
|
||||
* Perl's automated Test::Harness as well as generating human-readable output.
|
||||
* The routines detect whether they are being run automatically and print a
|
||||
* summary of the results at the end if not.
|
||||
|
||||
* A test program starts with a call to testPlan(), announcing how many tests
|
||||
* are to be conducted. If this number is not known a value of zero can be
|
||||
* used during development, but it is recommended that the correct value be
|
||||
* substituted after the test program has been completed.
|
||||
*
|
||||
* Individual test results are reported using any of testOk(), testOk1(),
|
||||
* testOkV(), testPass() or testFail(). The testOk() call takes and also
|
||||
* returns a logical pass/fail result (zero means failure, any other value
|
||||
* is success) and a printf-like format string and arguments which describe
|
||||
* the test. The convenience macro testOk1() is provided which stringifies its
|
||||
* single condition argument, reducing the effort needed when writing test
|
||||
* programs. The individual testPass() and testFail() routines can be used when
|
||||
* the test program takes a different path on success than on failure, but one
|
||||
* or other must always be called for any particular test. The testOkV() routine
|
||||
* is a varargs form of testOk() included for internal purposes which may prove
|
||||
* useful in some cases.
|
||||
*
|
||||
* If some program condition or failure makes it impossible to run some tests,
|
||||
* the testSkip() routine can be used to indicate how many tests are being omitted
|
||||
* from the run, thus keeping the test counts correct; the constant string why is
|
||||
* displayed as an explanation to the user (this string is not printf-like).
|
||||
*
|
||||
* If some tests are expected to fail because functionality in the module under
|
||||
* test has not yet been fully implemented, these tests may still be executed,
|
||||
* wrapped between calls to testTodoBegin() and testTodoEnd(). testTodoBegin()
|
||||
* takes a constant string indicating why these tests are not expected to
|
||||
* succeed. This modifies the counting of the results so the wrapped tests will not
|
||||
* be recorded as failures.
|
||||
*
|
||||
* Additional information can be supplied using the testDiag() routine, which
|
||||
* displays the relevent information as a comment in the result output. None of
|
||||
* the printable strings passed to any testXxx() routine should contain a newline
|
||||
* '\n' character, newlines will be added by the test routines as part of the
|
||||
* Test Anything Protocol. For multiple lines of diagnostic output, call
|
||||
* testDiag() as many times as necessary.
|
||||
*
|
||||
* If at any time the test program is unable to continue for some catastrophic
|
||||
* reason, calling testAbort() with an appropriate message will ensure that the
|
||||
* test harness understands this. testAbort() does not return, but calls the ANSI
|
||||
* C routine abort() to cause the program to stop immediately.
|
||||
*
|
||||
* After all of the tests have been completed, the return value from
|
||||
* testDone() can be used as the return status code from the program's main()
|
||||
* routine.
|
||||
*
|
||||
* On vxWorks and RTEMS, an alternative test harness can be used to run a
|
||||
* series of tests in order and summarize the results from them all at the end
|
||||
* just like the Perl harness does. The routine testHarness() is called once at
|
||||
* the beginning of the test harness program. Each test program is run by
|
||||
* passing its main routine name to the runTest() macro which expands into a call
|
||||
* to the runTestFunc() routine. The last test program or the harness program
|
||||
* itself must finish by calling testHarnessDone() which triggers the summary
|
||||
* mechanism to generate its result outputs (from an epicsAtExit() callback
|
||||
* routine).
|
||||
*
|
||||
* ### IOC Testing
|
||||
*
|
||||
* Some tests require the context of an IOC to be run. This conflicts with the
|
||||
* idea of running multiple tests within a test harness, as iocInit() is only
|
||||
* allowed to be called once, and some parts of the full IOC (e.g. the rsrv CA
|
||||
* server) can not be shut down cleanly. The function iocBuildIsolated() allows
|
||||
* to start an IOC without its Channel Access parts, so that it can be shutdown
|
||||
* quite cleanly using iocShutdown(). This feature is only intended to be used
|
||||
* from test programs, do not use it on productional IOCs. After building the
|
||||
* IOC using iocBuildIsolated() or iocBuild(), it has to be started by calling
|
||||
* iocRun(). The suggested call sequence in a test program that needs to run the
|
||||
* IOC without Channel Access is:
|
||||
\code
|
||||
#include "iocInit.h"
|
||||
|
||||
MAIN(iocTest)
|
||||
{
|
||||
iocBuildIsolated() || iocRun();
|
||||
|
||||
... test code ...
|
||||
|
||||
iocShutdown();
|
||||
dbFreeBase(pdbbase);
|
||||
registryFree();
|
||||
pdbbase = NULL;
|
||||
return testDone();
|
||||
}
|
||||
\endcode
|
||||
|
||||
* The part from iocBuildIsolated() to iocShutdown() can be repeated to
|
||||
* execute multiple tests within one executable or harness.
|
||||
*
|
||||
* To make it easier to create a single test program that can be built for
|
||||
* both the embedded and workstation operating system harnesses, the header file
|
||||
* testMain.h provides a convenience macro MAIN() that adjusts the name of the
|
||||
* test program according to the platform it is running on: main() on
|
||||
* workstations and a regular function name on embedded systems.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* The following is a simple example of a test program using the epicsUnitTest
|
||||
* routines:
|
||||
\code
|
||||
#include <math.h>
|
||||
#include "epicsUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
MAIN(mathTest)
|
||||
{
|
||||
testPlan(3);
|
||||
testOk(sin(0.0) == 0.0, "Sine starts");
|
||||
testOk(cos(0.0) == 1.0, "Cosine continues");
|
||||
if (!testOk1(M_PI == 4.0*atan(1.0)))
|
||||
testDiag("4 * atan(1) = %g", 4.0 * atan(1.0));
|
||||
return testDone();
|
||||
}
|
||||
\endcode
|
||||
|
||||
* The output from running the above program looks like this:
|
||||
\code
|
||||
1..3
|
||||
ok 1 - Sine starts
|
||||
ok 2 - Cosine continues
|
||||
ok 3 - M_PI == 4.0*atan(1.0)
|
||||
|
||||
Results
|
||||
=======
|
||||
Tests: 3
|
||||
Passed: 3 = 100%
|
||||
\endcode
|
||||
*/
|
||||
|
||||
#ifndef INC_epicsUnitTest_H
|
||||
@@ -21,35 +155,111 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Declare the test plan, required.
|
||||
* \param tests Number of tests to be run. May be zero if not known but the
|
||||
* test harness then can't tell if the program dies prematurely.
|
||||
*/
|
||||
epicsShareFunc void testPlan(int tests);
|
||||
epicsShareFunc int testOkV(int pass, const char *fmt, va_list pvar);
|
||||
epicsShareFunc int testOk(int pass, const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(2, 3);
|
||||
epicsShareFunc void testPass(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
epicsShareFunc void testFail(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
epicsShareFunc void testSkip(int skip, const char *why);
|
||||
epicsShareFunc void testTodoBegin(const char *why);
|
||||
epicsShareFunc void testTodoEnd(void);
|
||||
epicsShareFunc int testDiag(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
epicsShareFunc void testAbort(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
epicsShareFunc int testDone(void);
|
||||
|
||||
/** \name Announcing Test Results
|
||||
* Routines that declare individual test results.
|
||||
*/
|
||||
/** @{ */
|
||||
/** \brief Test result with printf-style description.
|
||||
* \param pass True/False value indicating result.
|
||||
* \param fmt A printf-style format string describing the test.
|
||||
* \param ... Any parameters required for the format string.
|
||||
* \return The value of \p pass.
|
||||
*/
|
||||
epicsShareFunc int testOk(int pass, const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(2, 3);
|
||||
/** \brief Test result using condition as description
|
||||
* \param cond Condition to be evaluated and displayed.
|
||||
* \return The value of \p cond.
|
||||
*/
|
||||
#define testOk1(cond) testOk(cond, "%s", #cond)
|
||||
/** \brief Test result with var-args description.
|
||||
* \param pass True/False value indicating result.
|
||||
* \param fmt A printf-style format string describing the test.
|
||||
* \param pvar A var-args pointer to any parameters for the format string.
|
||||
* \return The value of \p pass.
|
||||
*/
|
||||
epicsShareFunc int testOkV(int pass, const char *fmt, va_list pvar);
|
||||
/** \brief Passing test result with printf-style description.
|
||||
* \param fmt A printf-style format string describing the test.
|
||||
* \param ... Any parameters required for the format string.
|
||||
* \return The value of \p pass.
|
||||
*/
|
||||
epicsShareFunc void testPass(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
/** \brief Failing test result with printf-style description.
|
||||
* \param fmt A printf-style format string describing the test.
|
||||
* \param ... Any parameters required for the format string.
|
||||
*/
|
||||
epicsShareFunc void testFail(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
/** @} */
|
||||
|
||||
/** \name Missing or Failing Tests
|
||||
* \brief Routines for handling special situations.
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
/** \brief Place-holders for tests that can't be run.
|
||||
* \param skip How many tests are being skipped.
|
||||
* \param why Reason for skipping these tests.
|
||||
*/
|
||||
epicsShareFunc void testSkip(int skip, const char *why);
|
||||
/** \brief Mark the start of a group of tests that are expected to fail
|
||||
* \param why Reason for expected failures.
|
||||
*/
|
||||
epicsShareFunc void testTodoBegin(const char *why);
|
||||
/** \brief Mark the end of a failing test group.
|
||||
*/
|
||||
epicsShareFunc void testTodoEnd(void);
|
||||
/** \brief Stop testing, program cannot continue.
|
||||
* \param fmt A printf-style format string giving the reason for stopping.
|
||||
* \param ... Any parameters required for the format string.
|
||||
*/
|
||||
epicsShareFunc void testAbort(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
/** @} */
|
||||
|
||||
/** \brief Output additional diagnostics
|
||||
* \param fmt A printf-style format string containing diagnostic information.
|
||||
* \param ... Any parameters required for the format string.
|
||||
*/
|
||||
epicsShareFunc int testDiag(const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(1, 2);
|
||||
/** \brief Mark the end of testing.
|
||||
*/
|
||||
epicsShareFunc int testDone(void);
|
||||
|
||||
epicsShareFunc
|
||||
int testImpreciseTiming(void);
|
||||
|
||||
/** \name Test Harness for Embedded OSs
|
||||
* These routines are used to create a test-harness that can run
|
||||
* multiple test programs, collect their names and results, then
|
||||
* display a summary at the end of testing.
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
typedef int (*TESTFUNC)(void);
|
||||
/** \brief Initialize test harness
|
||||
*/
|
||||
epicsShareFunc void testHarness(void);
|
||||
epicsShareFunc void testHarnessExit(void *dummy);
|
||||
epicsShareFunc void runTestFunc(const char *name, TESTFUNC func);
|
||||
|
||||
/** \brief Run a test program
|
||||
* \param func Name of the test program.
|
||||
*/
|
||||
#define runTest(func) runTestFunc(#func, func)
|
||||
/** \brief Declare all test programs finished
|
||||
*/
|
||||
#define testHarnessDone() testHarnessExit(0)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -4,38 +4,48 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Compiler specific key words to set up external symbols and entry points
|
||||
/**
|
||||
* \file shareLib.h
|
||||
* \brief Mark external symbols and entry points for shared libraries.
|
||||
*
|
||||
* This is the header file for the "decorated names" that appear in
|
||||
* header files, e.g.
|
||||
*
|
||||
* #define epicsExportSharedSymbols
|
||||
* epicsShareFunc int epicsShareAPI a_func(int arg);
|
||||
*
|
||||
* These are needed to properly create DLLs on MS Windows.
|
||||
*
|
||||
* ### USAGE
|
||||
*
|
||||
* USAGE:
|
||||
* There are two distinct classes of keywords in this file:
|
||||
*
|
||||
* 1) epicsShareAPI - specifies a multi-language calling mechanism. On windows
|
||||
* -# epicsShareAPI - specifies a multi-language calling mechanism. On windows
|
||||
* this is the pascal calling convention which is used by visual basic and other
|
||||
* high level tools. This is only necessary if a C/C++ function needs to be called
|
||||
* from other languages or from high level tools. The epicsShareAPI keyword
|
||||
* must be present between the function's returned data type and the function's
|
||||
* name. All compilers targeting windows accept the __stdcall keyword in this
|
||||
* must be present between the function's returned data type and the function's
|
||||
* name. All compilers targeting windows accept the __stdcall keyword in this
|
||||
* location. Functions with variable argument lists should not use the epicsShareAPI
|
||||
* keyword because __stdcall (pascal) calling convention cannot support variable
|
||||
* length ed argument lists.
|
||||
*
|
||||
* int epicsShareAPI myExtFunc ( int arg );
|
||||
* int epicsShareAPI myExtFunc ( int arg ) {}
|
||||
* int epicsShareAPI myExtFunc ( int arg );
|
||||
* int epicsShareAPI myExtFunc ( int arg ) {}
|
||||
*
|
||||
* ** NOTE ** The epicsShareAPI attribute is deprecated and has been removed
|
||||
* \note The epicsShareAPI attribute is deprecated and has been removed
|
||||
* from all IOC-specific APIs. Most libCom APIs still use it, but
|
||||
* it may get removed from these at some point in the future.
|
||||
*
|
||||
* 2) epicsShare{Func,Class,Extern,Def} - specifies shareable library (DLL)
|
||||
* export/import related information in the source code. On windows these keywords
|
||||
* allow faster dispatching of calls to DLLs because more is known at compile time.
|
||||
* -# epicsShare{Func,Class,Extern,Def} - specifies shareable library (DLL)
|
||||
* export/import related information in the source code. On windows these keywords
|
||||
* allow faster dispatching of calls to DLLs because more is known at compile time.
|
||||
* It is also not necessary to maintain a linker input files specifying the DLL
|
||||
* entry points. This maintenance can be more laborious with C++ decorated symbol
|
||||
* names. These keywords are only necessary if the address of a function or data
|
||||
* internal to a shareable library (DLL) needs to be visible outside of this shareable
|
||||
* entry points. This maintenance can be more laborious with C++ decorated symbol
|
||||
* names. These keywords are only necessary if the address of a function or data
|
||||
* internal to a shareable library (DLL) needs to be visible outside of this shareable
|
||||
* library (DLL). All compilers targeting windows accept the __declspec(dllexport)
|
||||
* and __declspec(dllimport) keywords. For GCC version 4 and above the first three
|
||||
* keywords specify a visibility attribute of "default", which marks the symbol as
|
||||
@@ -43,23 +53,23 @@
|
||||
* significantly reduce the number of symbols exported to a shared library. See the
|
||||
* URL below for more information.
|
||||
*
|
||||
* In header files declare references to externally visible variables, classes and
|
||||
* In header files declare references to externally visible variables, classes and
|
||||
* functions like this:
|
||||
*
|
||||
* #include "shareLib.h"
|
||||
* epicsShareFunc int myExtFunc ( int arg );
|
||||
* epicsShareExtern int myExtVar;
|
||||
* class epicsShareClass myClass { int func ( void ); };
|
||||
* #include "shareLib.h"
|
||||
* epicsShareFunc int myExtFunc ( int arg );
|
||||
* epicsShareExtern int myExtVar;
|
||||
* class epicsShareClass myClass { int func ( void ); };
|
||||
*
|
||||
* In the implementation file, however, you write:
|
||||
*
|
||||
* #include <interfaces_imported_from_other_shareable_libraries.h>
|
||||
* #define epicsExportSharedSymbols
|
||||
* #include <interfaces_implemented_in_this_shareable_library.h>
|
||||
* #include <interfaces_imported_from_other_shareable_libraries.h>
|
||||
* #define epicsExportSharedSymbols
|
||||
* #include <interfaces_implemented_in_this_shareable_library.h>
|
||||
*
|
||||
* epicsShareDef int myExtVar = 4;
|
||||
* int myExtFunc ( int arg ) {}
|
||||
* int myClass::func ( void ) {}
|
||||
* epicsShareDef int myExtVar = 4;
|
||||
* int myExtFunc ( int arg ) {}
|
||||
* int myClass::func ( void ) {}
|
||||
*
|
||||
* By default shareLib.h sets the DLL import / export keywords to import from
|
||||
* a DLL so that, for DLL consumers (users), nothing special must be done. However,
|
||||
@@ -67,34 +77,42 @@
|
||||
* which functions are exported from the DLL and which of them are imported
|
||||
* from other DLLs.
|
||||
*
|
||||
* You must first #include what you import and then define epicsExportSharedSymbols
|
||||
* only right before you #include the prototypes for what you implement! You must
|
||||
* include shareLib.h again each time that the state of the import/ export keywords
|
||||
* changes, but this usually occurs as a side effect of including the shareable
|
||||
* libraries header file(s).
|
||||
* You must first \c \#include what you import and then \c \#define
|
||||
* \c epicsExportSharedSymbols only right before you \c \#include the
|
||||
* prototypes for what you implement! You must include shareLib.h again each
|
||||
* time that the state of the import/export keywords changes, but this
|
||||
* usually occurs as a side effect of including the shareable libraries header
|
||||
* file(s).
|
||||
*
|
||||
* Frequently a header file for a shareable library exported interface will
|
||||
* have some preprocessor switches like this if this header file must also
|
||||
* ### Deprecated Usage
|
||||
*
|
||||
* The construct described below is used in some EPICS header files bit is
|
||||
* no longer recommended as it makes it difficult to diagnose the incorrect
|
||||
* inclusion of headers that are the wrong side of an \c epicsExportSharedSymbols
|
||||
* marker.
|
||||
*
|
||||
* Sometimes a header file for a shareable library exported interface will
|
||||
* have some preprocessor switches like this if this header file must also
|
||||
* include header files describing interfaces to other shareable libraries.
|
||||
*
|
||||
* #ifdef epicsExportSharedSymbols
|
||||
* # define interfacePDQ_epicsExportSharedSymbols
|
||||
* # undef epicsExportSharedSymbols
|
||||
* #endif
|
||||
* #ifdef epicsExportSharedSymbols
|
||||
* # define interfacePDQ_epicsExportSharedSymbols
|
||||
* # undef epicsExportSharedSymbols
|
||||
* #endif
|
||||
*
|
||||
* #include "epicsTypes.h"
|
||||
* #include "epicsTime.h"
|
||||
* #include "epicsTypes.h"
|
||||
* #include "epicsTime.h"
|
||||
*
|
||||
* #ifdef interfacePDQ_epicsExportSharedSymbols
|
||||
* # define epicsExportSharedSymbols
|
||||
* # include "shareLib.h"
|
||||
* #endif
|
||||
* #ifdef interfacePDQ_epicsExportSharedSymbols
|
||||
* # define epicsExportSharedSymbols
|
||||
* # include "shareLib.h"
|
||||
* #endif
|
||||
*
|
||||
* epicsShareFunc int myExtFunc ( int arg );
|
||||
* epicsShareExtern int myExtVar;
|
||||
* class epicsShareClass myClass {};
|
||||
* epicsShareFunc int myExtFunc ( int arg );
|
||||
* epicsShareExtern int myExtVar;
|
||||
* class epicsShareClass myClass {};
|
||||
*
|
||||
* Fortunately, the above is only the concern of library authors and will have no
|
||||
* Fortunately, the above is only the concern of library authors and will have no
|
||||
* impact on persons using functions and or external data from a library.
|
||||
*/
|
||||
|
||||
@@ -132,7 +150,7 @@
|
||||
# define epicsShareFunc
|
||||
# endif
|
||||
# endif
|
||||
# define epicsShareDef
|
||||
# define epicsShareDef
|
||||
# define epicsShareAPI __stdcall /* function removes arguments */
|
||||
# define READONLY const
|
||||
|
||||
@@ -162,18 +180,18 @@
|
||||
*/
|
||||
#elif defined(VAXC)
|
||||
|
||||
/*
|
||||
/*
|
||||
* VAXC creates FORTRAN common blocks when
|
||||
* we use "extern int fred"/"int fred=4". Therefore,
|
||||
* the initialization is not loaded unless we
|
||||
* call a function in that object module.
|
||||
*
|
||||
* DEC CXX does not have this problem.
|
||||
* We suspect (but do not know) that DEC C
|
||||
* We suspect (but do not know) that DEC C
|
||||
* also does not have this problem.
|
||||
*/
|
||||
# define epicsShareExtern globalref
|
||||
# define epicsShareDef globaldef
|
||||
# define epicsShareExtern globalref
|
||||
# define epicsShareDef globaldef
|
||||
# define READONLY const
|
||||
# define epicsShareClass
|
||||
# define epicsShareFunc
|
||||
|
||||
@@ -24,13 +24,13 @@ extern "C" {
|
||||
#define OSI_PATH_SEPARATOR "/"
|
||||
|
||||
/** Return the absolute path of the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
\return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecName(void);
|
||||
|
||||
/** Return the absolute path of the directory containing the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
\return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecDir(void);
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
/**
|
||||
* \file compilerDependencies.h
|
||||
* \author Jeffrey O. Hill johill@lanl.gov
|
||||
* \brief Compiler specific declarations
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef compilerDependencies_h
|
||||
|
||||
@@ -8,93 +8,125 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devLib.h */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
/**
|
||||
* \file devLib.h
|
||||
* \brief API for accessing hardware devices, originally over VMEbus
|
||||
* \author Marty Kraimer and Jeff Hill
|
||||
*
|
||||
* Support for allocation of common device resources
|
||||
*/
|
||||
#ifndef EPICSDEVLIB_H
|
||||
#define EPICSDEVLIB_H
|
||||
|
||||
/*
|
||||
* Support macros
|
||||
*/
|
||||
|
||||
/*
|
||||
* Normalize a digital value and convert it to type TYPE
|
||||
*
|
||||
* Ex:
|
||||
* float f;
|
||||
* int d;
|
||||
* f = devNormalizeDigital(d,12)
|
||||
*
|
||||
/**
|
||||
* \name Macros for normalizing values
|
||||
* \warning Deprecated, we don't know of any code currently using these.
|
||||
* @{
|
||||
*/
|
||||
/** \brief Create a bit mask for a given number of bits */
|
||||
#define devCreateMask(NBITS) ((1<<(NBITS))-1)
|
||||
/** \brief Normalize a raw integer value and convert it to type double */
|
||||
#define devDigToNml(DIGITAL,NBITS) \
|
||||
(((double)(DIGITAL))/devCreateMask(NBITS))
|
||||
/** \brief Convert a normalized value to a raw integer */
|
||||
#define devNmlToDig(NORMAL,NBITS) \
|
||||
(((long)(NORMAL)) * devCreateMask(NBITS))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
*
|
||||
* Alignment mask
|
||||
* (for use when testing to see if the proper number of least
|
||||
* significant bits are zero)
|
||||
*
|
||||
/**
|
||||
* \name Macros for pointer alignment
|
||||
* \warning Deprecated, we don't know of any code currently using these.
|
||||
* @{
|
||||
*/
|
||||
/** \brief Create an alignment mask for CTYPE */
|
||||
#define devCreateAlignmentMask(CTYPE)\
|
||||
(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1)
|
||||
|
||||
/*
|
||||
* pointer aligned test
|
||||
* (returns true if the pointer is on the worst case alignemnt
|
||||
* boundary for its type)
|
||||
/** \brief Check Pointer alignment, returns true if the pointer \c PTR
|
||||
* is suitably aligned for its data type
|
||||
*/
|
||||
#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR)))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* error codes (and messages) associated with devLib.c
|
||||
/**
|
||||
* \name Error status values returned by devLib routines
|
||||
* @{
|
||||
*/
|
||||
#define S_dev_success 0
|
||||
#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/
|
||||
#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/
|
||||
#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/
|
||||
/** \brief Interrupt vector in use */
|
||||
#define S_dev_vectorInUse (M_devLib| 1) /*Interrupt vector in use*/
|
||||
/** \brief Interrupt vector install failed */
|
||||
#define S_dev_vecInstlFail (M_devLib| 2) /*Interrupt vector install failed*/
|
||||
/** \brief Unrecognized interrupt type */
|
||||
#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/
|
||||
/** \brief Interrupt vector not in use by caller */
|
||||
#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/
|
||||
/** \brief Invalid VME A16 address */
|
||||
#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/
|
||||
/** \brief Invalid VME A24 address */
|
||||
#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/
|
||||
/** \brief Invalid VME A32 address */
|
||||
#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/
|
||||
/** \brief Unrecognized address space type */
|
||||
#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/
|
||||
#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/
|
||||
#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/
|
||||
#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/
|
||||
#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/
|
||||
#define S_dev_internal (M_devLib| 13) /*Internal failure*/
|
||||
#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/
|
||||
#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/
|
||||
#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/
|
||||
#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/
|
||||
/** \brief Specified device address overlaps another device */
|
||||
#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/
|
||||
/** \brief This device already owns the address range */
|
||||
#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/
|
||||
/** \brief Unable to map address */
|
||||
#define S_dev_addrMapFail (M_devLib| 11) /*Unable to map address*/
|
||||
/** \brief Interrupt at vector disconnected from an EPICS device */
|
||||
#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/
|
||||
/** \brief Internal failure */
|
||||
#define S_dev_internal (M_devLib| 13) /*Internal failure*/
|
||||
/** \brief Unable to enable interrupt level */
|
||||
#define S_dev_intEnFail (M_devLib| 14) /*Unable to enable interrupt level*/
|
||||
/** \brief Unable to disable interrupt level */
|
||||
#define S_dev_intDissFail (M_devLib| 15) /*Unable to disable interrupt level*/
|
||||
/** \brief Memory allocation failed */
|
||||
#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/
|
||||
/** \brief Specified device address unregistered */
|
||||
#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/
|
||||
/** \brief No device at specified address */
|
||||
#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/
|
||||
/** \brief Wrong device type found at specified address */
|
||||
#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/
|
||||
/** \brief Signal number (offset) to large */
|
||||
#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/
|
||||
/** \brief Signal count to large */
|
||||
#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/
|
||||
/** \brief Device does not support requested operation */
|
||||
#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/
|
||||
#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/
|
||||
#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/
|
||||
/** \brief Parameter too high */
|
||||
#define S_dev_highValue (M_devLib| 23) /*Parameter too high*/
|
||||
/** \brief Parameter too low */
|
||||
#define S_dev_lowValue (M_devLib| 24) /*Parameter too low*/
|
||||
/** \brief Specified address is ambiguous (more than one device responds) */
|
||||
#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/
|
||||
/** \brief Device self test failed */
|
||||
#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/
|
||||
/** \brief Device failed during initialization */
|
||||
#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/
|
||||
/** \brief Input exceeds Hardware Limit */
|
||||
#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/
|
||||
/** \brief Unable to locate address space for device */
|
||||
#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/
|
||||
#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/
|
||||
#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/
|
||||
#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/
|
||||
#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/
|
||||
/** \brief Device timed out */
|
||||
#define S_dev_deviceTMO (M_devLib| 30) /*Device timed out*/
|
||||
/** \brief Bad function pointer */
|
||||
#define S_dev_badFunction (M_devLib| 31) /*Bad function pointer*/
|
||||
/** \brief Bad interrupt vector */
|
||||
#define S_dev_badVector (M_devLib| 32) /*Bad interrupt vector*/
|
||||
/** \brief Bad function argument */
|
||||
#define S_dev_badArgument (M_devLib| 33) /*Bad function argument*/
|
||||
/** \brief Invalid ISA address */
|
||||
#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/
|
||||
/** \brief Invalid VME CR/CSR address */
|
||||
#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/
|
||||
/** \brief Synonym for S_dev_intEnFail */
|
||||
#define S_dev_vxWorksIntEnFail S_dev_intEnFail
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* EPICSDEVLIB_H */
|
||||
|
||||
|
||||
@@ -4,14 +4,23 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devLib.h */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
/**
|
||||
* \file devLibVME.h
|
||||
* \author Marty Kraimer, Jeff Hill
|
||||
* \brief API for accessing hardware devices, mosty over VMEbus.
|
||||
*
|
||||
* API for accessing hardware devices. The original APIs here were for
|
||||
* written for use with VMEbus but additional routines were added for
|
||||
* ISA-bus (but not fully implemented inside EPICS Base and may never
|
||||
* have been actually used).
|
||||
*
|
||||
* If all VMEbus drivers register with these routines then addressing
|
||||
* conflicts caused by multiple device/drivers trying to use the same
|
||||
* VME addresses will be detected. This API also makes it easy for a
|
||||
* single driver to be written that works on both VxWorks and RTEMS.
|
||||
*/
|
||||
|
||||
#ifndef INCdevLibh
|
||||
@@ -27,23 +36,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* epdevAddressType & EPICStovxWorksAddrType
|
||||
* devLib.c must change in unison
|
||||
*/
|
||||
/** \brief The available bus address types */
|
||||
typedef enum {
|
||||
atVMEA16,
|
||||
atVMEA24,
|
||||
atVMEA32,
|
||||
atISA, /* memory mapped ISA access (until now only on PC) */
|
||||
atVMECSR, /* VME-64 CR/CSR address space */
|
||||
atLast /* atLast must be the last enum in this list */
|
||||
} epicsAddressType;
|
||||
atVMEA16, /**< \brief VME short I/O. */
|
||||
atVMEA24, /**< \brief VME standard I/O. */
|
||||
atVMEA32, /**< \brief VME extended I/O. */
|
||||
atISA, /**< \brief Memory mapped ISA access. */
|
||||
atVMECSR, /**< \brief VME-64 CR/CSR address space. */
|
||||
atLast /**< \brief Invalid, must be the last entry. */
|
||||
} epicsAddressType;
|
||||
|
||||
/*
|
||||
* pointer to an array of strings for each of
|
||||
* the above address types
|
||||
*/
|
||||
/** \brief A string representation of each of the bus address types */
|
||||
epicsShareExtern const char *epicsAddressTypeName[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -61,41 +64,54 @@ epicsShareExtern const char *epicsAddressTypeName[];
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General API
|
||||
/** \brief Print a map of registered bus addresses.
|
||||
*
|
||||
* This section applies to all bus types
|
||||
* Display a table of registsred bus address ranges, including the owner of
|
||||
* each registered address.
|
||||
* \return 0, or an error status value
|
||||
*/
|
||||
epicsShareFunc long devAddressMap(void);
|
||||
|
||||
epicsShareFunc long devAddressMap(void); /* print an address map */
|
||||
|
||||
/*
|
||||
* devBusToLocalAddr()
|
||||
/** \brief Translate a bus address to a pointer the CPU can use.
|
||||
*
|
||||
* OSI routine to translate bus addresses their local CPU address mapping
|
||||
* Given a bus address, returns a pointer to that location in the CPU's
|
||||
* memory map, or an error if direct access isn't currently possible.
|
||||
* \param addrType The bus address type.
|
||||
* \param busAddr Bus address to be translated.
|
||||
* \param *ppLocalAddr Where to put the CPU pointer.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devBusToLocalAddr (
|
||||
epicsAddressType addrType,
|
||||
size_t busAddr,
|
||||
volatile void **ppLocalAddr);
|
||||
/*
|
||||
* devReadProbe()
|
||||
|
||||
/** \brief Probe the bus for reading from a specific address.
|
||||
*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
* Performs a bus-error-safe \c wordSize atomic read from a specific
|
||||
* address and returns an error if this caused a bus error.
|
||||
* \param wordSize The word size to read: 1, 2, 4 or 8 bytes.
|
||||
* \param ptr Pointer to the location in the CPU's memory map to read.
|
||||
* \param pValueRead Where to put the value read.
|
||||
* \return 0, or an error status value if the location could not be
|
||||
* accessed or the read caused a bus error.
|
||||
*/
|
||||
epicsShareFunc long devReadProbe (
|
||||
unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* devNoResponseProbe()
|
||||
/** \brief Read-probe a range of bus addresses, looking for empty space.
|
||||
*
|
||||
* Verifies that no devices respond at naturally aligned words
|
||||
* within the specified address range. Return success if no devices
|
||||
* respond. Returns an error if a device does respond or if
|
||||
* a physical address for a naturally aligned word cant be mapped.
|
||||
* Checks all naturally aligned word sizes between char and long for
|
||||
* the entire specified range of bytes.
|
||||
* Verifies that no device responds at any naturally aligned addresses
|
||||
* within the given range. Tries to read every aligned address at every
|
||||
* word size between char and long over the entire range, returning
|
||||
* success only if none of the reads succeed.
|
||||
* \warning This routine may be slow and have a very bad effect on a busy
|
||||
* VMEbus. Every read probe of an unused address will hold onto the VMEbus
|
||||
* for the global bus timeout period.
|
||||
* \param addrType The bus address type.
|
||||
* \param base First address base to probe.
|
||||
* \param size Range of bus addresses to test, in bytes.
|
||||
* \return 0 if no devices respond, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devNoResponseProbe(
|
||||
epicsAddressType addrType,
|
||||
@@ -103,29 +119,71 @@ epicsShareFunc long devNoResponseProbe(
|
||||
size_t size
|
||||
);
|
||||
|
||||
/*
|
||||
* devWriteProbe
|
||||
/** \brief Probe the bus for writing to a specific address.
|
||||
*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
* Performs a bus-error-safe \c wordSize atomic write to a specific
|
||||
* address and returns an error if this caused a bus error.
|
||||
* \param wordSize The word size to write: 1, 2, 4 or 8 bytes.
|
||||
* \param ptr Pointer to the location in the CPU's memory map to write to.
|
||||
* \param pValueWritten The value to write.
|
||||
* \return 0, or an error status value if the location could not be
|
||||
* accessed or the write caused a bus error.
|
||||
*/
|
||||
epicsShareFunc long devWriteProbe (
|
||||
unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
/** \brief Register a bus address range with a name.
|
||||
*
|
||||
* The devLib code keeps a list of all bus address ranges registered with
|
||||
* this routine and returns an error if a later call attempts to register
|
||||
* any addresses that overlap with a range already registered. The call to
|
||||
* registering a range also converts the given base address into a pointer
|
||||
* in the CPU address space for the driver to use (see devBusToLocalAddr()).
|
||||
* \param pOwnerName Name of a driver that will own this range.
|
||||
* \param addrType The bus address type.
|
||||
* \param logicalBaseAddress The bus start address.
|
||||
* \param size Number of bytes to reserve.
|
||||
* \param pPhysicalAddress Where to put the converted CPU pointer.
|
||||
* \return 0, or an error status.
|
||||
*/
|
||||
epicsShareFunc long devRegisterAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
size_t size, /* bytes */
|
||||
size_t size,
|
||||
volatile void **pPhysicalAddress);
|
||||
|
||||
/** \brief Release a bus address range previously registered.
|
||||
*
|
||||
* Release an address range that was previously registered by a call to
|
||||
* devRegisterAddress() or devAllocAddress().
|
||||
* \param addrType The bus address type.
|
||||
* \param logicalBaseAddress The bus start address.
|
||||
* \param pOwnerName The name of the driver that owns this range.
|
||||
* \return 0, or an error status.
|
||||
*/
|
||||
epicsShareFunc long devUnregisterAddress(
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
const char *pOwnerName);
|
||||
|
||||
/*
|
||||
* allocate and register an unoccupied address block
|
||||
/** \brief Allocate and register an unoccupied address block.
|
||||
*
|
||||
* Asks devLib to allocate an address block of a particular address type.
|
||||
* This is useful for devices that appear in more than one address space
|
||||
* and can program the base address of one window using registers found
|
||||
* in another window. As with devRegisterAddress() this call also converts
|
||||
* the new base address into a pointer in the CPU address space for the
|
||||
* driver to use (see devBusToLocalAddr()).
|
||||
* \note This routine calls devNoResponseProbe() to find an unoccupied
|
||||
* block in the bus address space, so using it may have a bad effect on a
|
||||
* busy VMEbus at allocation time; see the warning above.
|
||||
* \param pOwnerName Name of a driver that will own this range.
|
||||
* \param addrType The bus address type.
|
||||
* \param size Number of bytes to be allocated.
|
||||
* \param alignment How many low bits in the address must all be zero.
|
||||
* \param pLocalAddress Where to put the CPU pointer.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devAllocAddress(
|
||||
const char *pOwnerName,
|
||||
@@ -134,117 +192,185 @@ epicsShareFunc long devAllocAddress(
|
||||
unsigned alignment, /*n ls bits zero in addr*/
|
||||
volatile void **pLocalAddress);
|
||||
|
||||
/*
|
||||
* VME API
|
||||
*
|
||||
* Functions in this section apply only to the VME bus type
|
||||
/** \name VME Interrupt Management
|
||||
* Routines to manage VME interrupts.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
/** \brief Connect an ISR up to a VME interrupt vector.
|
||||
*
|
||||
* Interrupt Service Routines (ISRs) are normally written in C, and get
|
||||
* passed a context parameter given with them to this connection routine.
|
||||
*
|
||||
* There are many restrictions on the routines that an ISR may call; see
|
||||
* epicsEvent.h, epicsInterrupt.h, epicsMessageQueue.h, epicsRingBytes.h,
|
||||
* epicsRingPointer.h and epicsTime.h for some APIs known to be suitable.
|
||||
* It is safest just to trigger a high-priority task to handle any
|
||||
* complex work that must happen as a result of the interrupt.
|
||||
* \param vectorNumber VME interrupt vector number.
|
||||
* \param pFunction The ISR to be called.
|
||||
* \param parameter Context parameter for the ISR.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
/** \brief Disconnect an ISR from its VME interrupt vector.
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
* Device drivers may disconnect an ISR they connected earlier using this
|
||||
* routine. In addition to taking the \c vectorNumber the ISR itself is
|
||||
* required and used as a check to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install.
|
||||
*
|
||||
* On a PowerPC target running VxWorks, this routine will always return
|
||||
* with an error status.
|
||||
* \param vectorNumber VME interrupt vector number.
|
||||
* \param pFunction The ISR to be disconnected.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* determine if a VME interrupt vector is in use
|
||||
/** \brief Determine if a VME interrupt vector is in use.
|
||||
*
|
||||
* returns boolean
|
||||
* On a PowerPC target running VxWorks this routine will always return
|
||||
* false, indicating that a vector is unused.
|
||||
* \param vectorNumber Interrupt vector number.
|
||||
* \return True if vector has an ISR attached, otherwise false.
|
||||
*/
|
||||
epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
/** \brief Enable a VME interrupt level onto the CPU.
|
||||
*
|
||||
* The VMEbus allows multiple CPU boards to be installed in the same
|
||||
* backplane. When this is done, the differente VME interrupt levels
|
||||
* must be assigned to the CPUs since they cannot be shared. This
|
||||
* routine tells the VME interface that it should connect interrupts
|
||||
* from the indicated interrupt level to a CPU interrupt line.
|
||||
* \param level VMEbus interrupt level to enable, 1-7.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
/** \brief Disable a VME interrupt level.
|
||||
*
|
||||
* This routine is the reverse of devEnableInterruptLevelVME().
|
||||
* \note This routine should not normally be used, even by a
|
||||
* driver that enabled the interrupt level. Disabling a VME
|
||||
* interrupt level should only be done by software that knows
|
||||
* for certain that no other interrupting device is also using
|
||||
* that VME interrupt level.
|
||||
* \param level VMEbus interrupt level to disable, 1-7.
|
||||
* \return 0, or an error status value.
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Routines to allocate and free memory in the A24 memory region.
|
||||
*
|
||||
/** \name Memory for VME DMA Operations
|
||||
* These routines manage memory that can be directly accessed
|
||||
* from the VMEbus in the A24 address space by another bus master
|
||||
* such as a DMA controller.
|
||||
* @{
|
||||
*/
|
||||
/** \brief malloc() for VME drivers that support DMA.
|
||||
*
|
||||
* Allocate memory of a given size from a region that can be
|
||||
* accessed from the VMEbus in the A24 address space.
|
||||
* \param size How many bytes to allocate
|
||||
* \return A pointer to the memory allocated, or NULL.
|
||||
*/
|
||||
epicsShareFunc void *devLibA24Malloc(size_t size);
|
||||
|
||||
/** \brief calloc() for VME drivers that support DMA.
|
||||
*
|
||||
* Allocate and zero-fill a block of memory of a given size from
|
||||
* a region that can be accessed from the VMEbus in the A24
|
||||
* address space.
|
||||
* \param size How many bytes to allocate and zero.
|
||||
* \return A pointer to the memory allocated, or NULL.
|
||||
*/
|
||||
epicsShareFunc void *devLibA24Calloc(size_t size);
|
||||
|
||||
/** \brief free() for VME drivers that support DMA.
|
||||
*
|
||||
* Free a block of memory that was allocated using either
|
||||
* devLibA24Malloc() or devLibA24Calloc().
|
||||
* \param pBlock Block to be released.
|
||||
*/
|
||||
epicsShareFunc void *devLibA24Malloc(size_t);
|
||||
epicsShareFunc void *devLibA24Calloc(size_t);
|
||||
epicsShareFunc void devLibA24Free(void *pBlock);
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* ISA API
|
||||
*
|
||||
* Functions in this section apply only to the ISA bus type
|
||||
/** \name ISA Interrupt Management
|
||||
* Routines to manage ISAbus interrupts.
|
||||
* \note These routines may not have been used for a very long time;
|
||||
* some appear to have never been implemented at all. They may vanish
|
||||
* with no notice from future versions of EPICS Base. Nobody is using
|
||||
* the PC's ISA-bus any more are they?
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* connect ISR to an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
/**
|
||||
* Connect ISR to a ISA interrupt.
|
||||
* \warning Not implemented!
|
||||
* \param interruptLevel Bus interrupt level to connect to.
|
||||
* \param pFunction C function pointer to connect to.
|
||||
* \param parameter Parameter to the called function.
|
||||
* \return Returns success or error.
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
/**
|
||||
* Disconnect ISR from a ISA interrupt level.
|
||||
* \warning Not implemented!
|
||||
* \param interruptLevel Interrupt level.
|
||||
* \param pFunction C function pointer that was connected.
|
||||
* \return returns success or error.
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* determine if an ISA interrupt level is in use
|
||||
* (not implemented)
|
||||
*
|
||||
* returns boolean
|
||||
/**
|
||||
* Determine if an ISA interrupt level is in use
|
||||
* \warning Not implemented!
|
||||
* \param interruptLevel Interrupt level.
|
||||
* \return Returns True/False.
|
||||
*/
|
||||
epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
|
||||
/*
|
||||
* enable ISA interrupt level
|
||||
/**
|
||||
* Enable ISA interrupt level
|
||||
* \param level Interrupt level.
|
||||
* \return Returns True/False.
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* disable ISA interrupt level
|
||||
/**
|
||||
* Disable ISA interrupt level
|
||||
* \param level Interrupt level.
|
||||
* \return Returns True/False.
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* Deprecated interface
|
||||
*/
|
||||
/** @} */
|
||||
|
||||
#ifndef NO_DEVLIB_OLD_INTERFACE
|
||||
|
||||
/**
|
||||
* \name Deprecated Interfaces
|
||||
* @{
|
||||
*/
|
||||
typedef enum {intVME, intVXI, intISA} epicsInterruptType;
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
/**
|
||||
* \note This routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devConnectInterruptVME, devConnectInterruptPCI,
|
||||
* devConnectInterruptISA etc. devConnectInterrupt will be removed
|
||||
* Please use one of devConnectInterruptVME(), devConnectInterruptPCI(),
|
||||
* devConnectInterruptISA() instead. devConnectInterrupt() will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devConnectInterrupt(
|
||||
@@ -253,50 +379,48 @@ epicsShareFunc long devConnectInterrupt(
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
/**
|
||||
* \note This routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI,
|
||||
* devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
|
||||
* in a future release.
|
||||
* Please use one of devDisconnectInterruptVME(), devDisconnectInterruptPCI(),
|
||||
* devDisconnectInterruptISA() instead. devDisconnectInterrupt() will
|
||||
* be removed in a future release.
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
/**
|
||||
* \note This routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI,
|
||||
* devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
* Please use one of devEnableInterruptLevelVME(), devEnableInterruptLevelPCI(),
|
||||
* devEnableInterruptLevelISA() instead. devEnableInterruptLevel() will
|
||||
* be removed in a future release.
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevel(
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
/**
|
||||
* \note This routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA,
|
||||
* devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
* Please use one of devDisableInterruptLevelVME(), devDisableInterruptLevelISA(),
|
||||
* devDisableInterruptLevelPCI() instead. devDisableInterruptLevel() will
|
||||
* be removed in a future release.
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevel (
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
/**
|
||||
* \note This routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use devNoResponseProbe(). locationProbe() will be removed
|
||||
* Please use devNoResponseProbe() instead. locationProbe() will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* NO_DEVLIB_OLD_INTERFACE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devLibImpl.h */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
/**
|
||||
* \file devLibVMEImpl.h
|
||||
* \author Marty Kraimer, Jeff Hill
|
||||
* \brief An interface from devLibVME.c to its OS-specific implementations.
|
||||
*/
|
||||
|
||||
#ifndef INCdevLibImplh
|
||||
@@ -27,72 +26,57 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* virtual OS layer for devLib.c
|
||||
/**
|
||||
* \brief A table of function pointers for devLibVME implementations
|
||||
*
|
||||
* The global virtual OS table pdevLibVME controls
|
||||
* The global virtual OS table \ref pdevLibVME controls
|
||||
* the behaviour of the functions defined in devLib.h.
|
||||
* All of which call into the functions found in this table
|
||||
* to perform system specific tasks.
|
||||
*/
|
||||
typedef struct devLibVME {
|
||||
/*
|
||||
* maps logical address to physical address, but does not detect
|
||||
* two device drivers that are using the same address range
|
||||
*/
|
||||
long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
|
||||
/** \brief Map a bus address to the CPU's address space. */
|
||||
long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
/** \brief Read a word, detect and protect against bus errors. */
|
||||
long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr,
|
||||
void *pValueRead);
|
||||
/** \brief Write a word, detect and protect against bus errors. */
|
||||
long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr,
|
||||
const void *pValueWritten);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
/** \brief Connect ISR to a VME interrupt vector. */
|
||||
long (*pDevConnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *), void *parameter);
|
||||
/** \brief Disconnect ISR from a VME interrupt vector. */
|
||||
long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevConnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *), void *parameter);
|
||||
/** \brief Enable VME interrupt level to CPU. */
|
||||
long (*pDevEnableInterruptLevelVME) (unsigned level);
|
||||
/** \brief Disable VME interrupt level to CPU. */
|
||||
long (*pDevDisableInterruptLevelVME) (unsigned level);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
/** \brief Malloc a block accessible from the VME A24 address space. */
|
||||
void *(*pDevA24Malloc)(size_t nbytes);
|
||||
/** \brief Free a block allocated for the VME A24 address space. */
|
||||
void (*pDevA24Free)(void *pBlock);
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long (*pDevEnableInterruptLevelVME) (unsigned level);
|
||||
/** \brief Init devLib */
|
||||
long (*pDevInit)(void);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long (*pDevDisableInterruptLevelVME) (unsigned level);
|
||||
/* malloc/free A24 address space */
|
||||
void *(*pDevA24Malloc)(size_t nbytes);
|
||||
void (*pDevA24Free)(void *pBlock);
|
||||
long (*pDevInit)(void);
|
||||
|
||||
/*
|
||||
* test if VME interrupt has an ISR connected
|
||||
*/
|
||||
int (*pDevInterruptInUseVME) (unsigned vectorNumber);
|
||||
/** \brief Check if interrupt vector has an ISR connected. */
|
||||
int (*pDevInterruptInUseVME)(unsigned vectorNumber);
|
||||
}devLibVME;
|
||||
|
||||
/** \brief Pointer to the entry table used by devLibVME routines. */
|
||||
epicsShareExtern devLibVME *pdevLibVME;
|
||||
|
||||
#ifndef NO_DEVLIB_COMPAT
|
||||
/** \brief An alias for pdevLibVME */
|
||||
# define pdevLibVirtualOS pdevLibVME
|
||||
/** \brief A type definition for devLibVME */
|
||||
typedef devLibVME devLibVirtualOS;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,14 +4,39 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* EPICS assert
|
||||
|
||||
/**\file epicsAssert.h
|
||||
* \author Jeffery O. Hill
|
||||
*
|
||||
* Author: Jeffrey O. Hill
|
||||
* Date: 022795
|
||||
*/
|
||||
* \brief An EPICS-specific replacement for ANSI C's assert.
|
||||
*
|
||||
* To use this version just include:
|
||||
\code
|
||||
#define epicsAssertAuthor "Code Author my@email.address"
|
||||
#include <epicsAssert.h>
|
||||
\endcode
|
||||
* instead of
|
||||
\code
|
||||
#include <assert.h>
|
||||
\endcode
|
||||
*
|
||||
* If an assert() fails, it calls errlog indicating the program's author, file name, and
|
||||
* line number. Under each OS there are specialized instructions assisting the user to
|
||||
* diagnose the problem and generate a good bug report. For instance, under vxWorks,
|
||||
* there are instructions on how to generate a stack trace, and on posix there are
|
||||
* instructions about saving the core file. After printing the message the calling thread
|
||||
* is suspended. An author may, before the above include line, optionally define a
|
||||
* preprocessor macro named epicsAssertAuthor as a string that provides their name and
|
||||
* email address if they wish to be contacted when the assertion fires.
|
||||
*
|
||||
* This header also provides a compile-time assertion macro STATIC_ASSERT()
|
||||
* which can be used to check a constant-expression at compile-time. The C or
|
||||
* C++ compiler will flag an error if the expresstion evaluates to 0. The
|
||||
* STATIC_ASSERT() macro can only be used where a \c typedef is syntactically
|
||||
* legal.
|
||||
**/
|
||||
|
||||
#ifndef INC_epicsAssert_H
|
||||
#define INC_epicsAssert_H
|
||||
@@ -25,6 +50,7 @@ extern "C" {
|
||||
|
||||
|
||||
#ifndef epicsAssertAuthor
|
||||
/**\brief Optional string giving the author's name */
|
||||
# define epicsAssertAuthor 0
|
||||
#endif
|
||||
|
||||
@@ -34,9 +60,13 @@ extern "C" {
|
||||
# define assert(ignore) ((void) 0)
|
||||
#else /* NDEBUG */
|
||||
|
||||
/**@private */
|
||||
epicsShareFunc void epicsAssert (const char *pFile, const unsigned line,
|
||||
const char *pExp, const char *pAuthorName);
|
||||
|
||||
/**\brief Declare that a condition should be true.
|
||||
* \param exp Expression that should evaluate to True.
|
||||
*/
|
||||
# define assert(exp) ((exp) ? (void)0 : \
|
||||
epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor))
|
||||
|
||||
@@ -49,6 +79,10 @@ epicsShareFunc void epicsAssert (const char *pFile, const unsigned line,
|
||||
#else
|
||||
#define STATIC_JOIN(x, y) STATIC_JOIN2(x, y)
|
||||
#define STATIC_JOIN2(x, y) x ## y
|
||||
|
||||
/**\brief Declare a condition that should be true at compile-time.
|
||||
* \param expr A C/C++ const-expression that should evaluate to True.
|
||||
*/
|
||||
#define STATIC_ASSERT(expr) \
|
||||
typedef int STATIC_JOIN(static_assert_failed_at_line_, __LINE__) \
|
||||
[ (expr) ? 1 : -1 ] EPICS_UNUSED
|
||||
|
||||
@@ -4,26 +4,62 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**\file epicsEvent.h
|
||||
*
|
||||
* \brief APIs for the epicsEvent binary semaphore.
|
||||
*
|
||||
* Defines the C++ and C API's for a simple binary semaphore. If multiple threads are
|
||||
* waiting on the same event, only one of them will be woken when the event is signalled.
|
||||
*
|
||||
* The primary use of an event semaphore is for thread synchronization. An example of using an
|
||||
* event semaphore is a consumer thread that processes requests from one or more producer threads.
|
||||
* For example:
|
||||
*
|
||||
* When creating the consumer thread also create an epicsEvent.
|
||||
\code
|
||||
epicsEvent *pevent = new epicsEvent;
|
||||
\endcode
|
||||
* The consumer thread has code containing:
|
||||
\code
|
||||
while(1) {
|
||||
pevent->wait();
|
||||
while( {more work} ) {
|
||||
{process work}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
* Producers create requests and issue the statement:
|
||||
\code
|
||||
pevent->trigger();
|
||||
\endcode
|
||||
**/
|
||||
|
||||
#ifndef epicsEventh
|
||||
#define epicsEventh
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/** \brief An identifier for an epicsEvent for use with the C API */
|
||||
typedef struct epicsEventOSD *epicsEventId;
|
||||
|
||||
/** \brief Return status from several C API routines. */
|
||||
typedef enum {
|
||||
epicsEventOK = 0,
|
||||
epicsEventWaitTimeout,
|
||||
epicsEventError
|
||||
} epicsEventStatus;
|
||||
|
||||
/* Backwards compatibility */
|
||||
/** \brief Old name provided for backwards compatibility */
|
||||
#define epicsEventWaitStatus epicsEventStatus
|
||||
/** \brief Old name provided for backwards compatibility */
|
||||
#define epicsEventWaitOK epicsEventOK
|
||||
/** \brief Old name provided for backwards compatibility */
|
||||
#define epicsEventWaitError epicsEventError
|
||||
|
||||
/** \brief Possible initial states of a new epicsEvent */
|
||||
typedef enum {
|
||||
epicsEventEmpty,
|
||||
epicsEventFull
|
||||
@@ -31,15 +67,50 @@ typedef enum {
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/**\brief A binary semaphore.
|
||||
*
|
||||
* An epicsEvent is a binary semaphore that can be empty or full.
|
||||
* When empty, a wait() issued before the next call to trigger() will block.
|
||||
* When full, the next call to wait() will empty the event and return
|
||||
* immediately. Multiple calls to trigger() may occur between wait() calls
|
||||
* but will have the same effect as a single trigger(), filling the event.
|
||||
**/
|
||||
class epicsShareClass epicsEvent {
|
||||
public:
|
||||
/**\brief Constructor.
|
||||
* \param initial State when created, empty (the default) or full.
|
||||
**/
|
||||
epicsEvent ( epicsEventInitialState initial = epicsEventEmpty );
|
||||
/**\brief Destroy the epicsEvent and any resources it holds. No calls to
|
||||
* wait() can be active when this call is made.
|
||||
**/
|
||||
~epicsEvent ();
|
||||
/**\brief Trigger the event i.e. ensures the next or current call to wait
|
||||
* completes. This method may be called from a vxWorks or RTEMS interrupt
|
||||
* handler.
|
||||
**/
|
||||
void trigger ();
|
||||
/**\brief Signal is a synonym for trigger().
|
||||
**/
|
||||
void signal () { this->trigger(); }
|
||||
void wait (); /* blocks until full */
|
||||
bool wait ( double timeOut ); /* false if still empty at time out */
|
||||
bool tryWait (); /* false if empty */
|
||||
/**\brief Wait for the event.
|
||||
* \note Blocks until full.
|
||||
**/
|
||||
void wait ();
|
||||
/**\brief Wait for the event or until the specified timeout.
|
||||
* \param timeOut The timeout delay in seconds.
|
||||
* \return True if the event was triggered, False if it timed out.
|
||||
**/
|
||||
bool wait ( double timeOut );
|
||||
/**\brief Similar to wait() except that if the event is currenly empty the
|
||||
* call will return immediately.
|
||||
* \return True if the event was full (triggered), False if empty.
|
||||
**/
|
||||
bool tryWait ();
|
||||
/**\brief Display information about the semaphore.
|
||||
* \note The information displayed is architecture dependant.
|
||||
* \param level An unsigned int for the level of information to be displayed.
|
||||
**/
|
||||
void show ( unsigned level ) const;
|
||||
|
||||
class invalidSemaphore; /* exception payload */
|
||||
@@ -52,22 +123,91 @@ private:
|
||||
extern "C" {
|
||||
#endif /*__cplusplus */
|
||||
|
||||
/**\brief Create an epicsEvent for use from C code, or return NULL.
|
||||
*
|
||||
* \param initialState Starting state, \c epicsEventEmpty or \c epicsEventFull.
|
||||
* \return An identifier for the new event, or NULL if one not be created.
|
||||
**/
|
||||
epicsShareFunc epicsEventId epicsEventCreate(
|
||||
epicsEventInitialState initialState);
|
||||
|
||||
/**\brief Create an epicsEvent for use from C code.
|
||||
*
|
||||
* This routine does not return if the object could not be created.
|
||||
* \param initialState Starting state, \c epicsEventEmpty or \c epicsEventFull.
|
||||
* \return An identifier for the new event.
|
||||
**/
|
||||
epicsShareFunc epicsEventId epicsEventMustCreate (
|
||||
epicsEventInitialState initialState);
|
||||
|
||||
/**\brief Destroy an epicsEvent and any resources it holds.
|
||||
*
|
||||
* No calls to any epicsEventWait routines can be active when this call is made.
|
||||
* \param id The event identifier.
|
||||
**/
|
||||
epicsShareFunc void epicsEventDestroy(epicsEventId id);
|
||||
|
||||
/**\brief Trigger an event i.e. ensures the next or current call to wait
|
||||
* completes.
|
||||
*
|
||||
* \note This method may be called from a VxWorks or RTEMS interrupt
|
||||
* handler.
|
||||
* \param id The event identifier.
|
||||
* \return Status indicator.
|
||||
**/
|
||||
epicsShareFunc epicsEventStatus epicsEventTrigger(
|
||||
epicsEventId id);
|
||||
|
||||
/**\brief Trigger an event.
|
||||
*
|
||||
* This routine does not return if the identifier is invalid.
|
||||
* \param id The event identifier.
|
||||
*/
|
||||
epicsShareFunc void epicsEventMustTrigger(epicsEventId id);
|
||||
|
||||
/**\brief A synonym for epicsEventTrigger().
|
||||
* \param ID The event identifier.
|
||||
* \return Status indicator.
|
||||
**/
|
||||
#define epicsEventSignal(ID) epicsEventMustTrigger(ID)
|
||||
|
||||
/**\brief Wait for an event.
|
||||
* \note Blocks until full.
|
||||
* \param id The event identifier.
|
||||
* \return Status indicator.
|
||||
**/
|
||||
epicsShareFunc epicsEventStatus epicsEventWait(
|
||||
epicsEventId id);
|
||||
|
||||
/**\brief Wait for an event (see epicsEventWait()).
|
||||
*
|
||||
* This routine does not return if the identifier is invalid.
|
||||
* \param id The event identifier.
|
||||
*/
|
||||
epicsShareFunc void epicsEventMustWait(epicsEventId id);
|
||||
|
||||
/**\brief Wait an the event or until the specified timeout period is over.
|
||||
* \note Blocks until full or timeout.
|
||||
* \param id The event identifier.
|
||||
* \param timeOut The timeout delay in seconds.
|
||||
* \return Status indicator.
|
||||
**/
|
||||
epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(
|
||||
epicsEventId id, double timeOut);
|
||||
|
||||
/**\brief Similar to wait() except that if the event is currenly empty the
|
||||
* call will return immediately with status \c epicsEventWaitTimeout.
|
||||
* \param id The event identifier.
|
||||
* \return Status indicator, \c epicsEventWaitTimeout when the event is empty.
|
||||
**/
|
||||
epicsShareFunc epicsEventStatus epicsEventTryWait(
|
||||
epicsEventId id);
|
||||
|
||||
/**\brief Display information about the semaphore.
|
||||
* \note The information displayed is architecture dependant.
|
||||
* \param id The event identifier.
|
||||
* \param level An unsigned int for the level of information to be displayed.
|
||||
**/
|
||||
epicsShareFunc void epicsEventShow(
|
||||
epicsEventId id, unsigned int level);
|
||||
|
||||
|
||||
@@ -7,6 +7,32 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**\file epicsGeneralTime.h
|
||||
*
|
||||
* \brief The generalTime framework provides a mechanism for several time providers to be
|
||||
* present within the system.
|
||||
*
|
||||
* There are two types of time provider, one type provides the current wall-clock
|
||||
* time, the other provides Event System times. Each time provider is registered with
|
||||
* a priority, and installed providers are queried in priority order whenever a time
|
||||
* is requested, until one returns successfully. Thus there is a fallback from higher
|
||||
* priority providers (smaller value of priority) to lower priority providers (larger
|
||||
* value of priority) if the highest priority ones fail. Each architecture has a "last
|
||||
* resort" provider, installed at priority 999, usually based on the system clock, which
|
||||
* is used in the absence of any other provider.
|
||||
*
|
||||
* Targets running VxWorks and RTEMS have an NTP provider installed at priority 100.
|
||||
*
|
||||
* Registered providers may also add an interrupt-safe routine that will be called from
|
||||
* the epicsTimeGetCurrentInt() or epicsTimeGetEventInt() API routines. These interfaces
|
||||
* cannot check the priority queue, so will only succeed if the last-used provider has
|
||||
* registered a suitable routine.
|
||||
*
|
||||
* \note There are two interfaces to this framework, epicsGeneralTime.h for consumers
|
||||
* to obtain a time and query the framework, and generalTimeSup.h for providers
|
||||
* that can supply timestamps.
|
||||
**/
|
||||
|
||||
#ifndef INC_epicsGeneralTime_H
|
||||
#define INC_epicsGeneralTime_H
|
||||
|
||||
@@ -16,28 +42,109 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**\def NUM_TIME_EVENTS
|
||||
* \brief The number of time events that are validated.
|
||||
*
|
||||
* Time Events numbered 0 through (NUM_TIME_EVENTS-1) are validated by code in
|
||||
* epicsGeneralTime.c that tests for advancing timestamps and enforces that
|
||||
* restriction.
|
||||
*
|
||||
* \note Event numbers greater than or equal to NUM_TIME_EVENTS are now allowed
|
||||
* if supported by a custom time provider which should provide its own advancing
|
||||
* timestamp validation.
|
||||
**/
|
||||
#define NUM_TIME_EVENTS 256
|
||||
/* Time Events numbered 0 through (NUM_TIME_EVENTS-1) are validated by */
|
||||
/* code in epicsGeneralTime.c that tests for advancing timestamps and */
|
||||
/* enforces that restriction. Event numbers greater than or equal to */
|
||||
/* NUM_TIME_EVENTS are now allowed if supported by a custom time provider */
|
||||
/* which should provide its own advancing timestamp validation. */
|
||||
|
||||
/**\brief Initialise the framework.
|
||||
*
|
||||
* This routine is called automatically by any function that requires the
|
||||
* framework. It does not need to be called explicitly.
|
||||
**/
|
||||
epicsShareFunc void generalTime_Init(void);
|
||||
|
||||
/**\brief Install a Time Event time provider that returns the current time for any
|
||||
* Time event number.
|
||||
*
|
||||
* \note This is optional as it is site policy whether the last resort for a Time
|
||||
* Event time in the absence of any working provider should be a failure, or the
|
||||
* current time.
|
||||
**/
|
||||
epicsShareFunc int installLastResortEventProvider(void);
|
||||
|
||||
/**\brief Reset the internal counter of the number of times the time returned was
|
||||
* earlier than when previously requested.
|
||||
*
|
||||
* Used by device support for binary out record
|
||||
* with:
|
||||
\code
|
||||
DTYP = "General Time"
|
||||
OUT = "@RSTERRCNT"
|
||||
\endcode
|
||||
**/
|
||||
epicsShareFunc void generalTimeResetErrorCounts(void);
|
||||
|
||||
/**\brief Return the internal counter of the number of times the time returned was
|
||||
* earlier than when previously requested.
|
||||
*
|
||||
* Used by device support for longin record
|
||||
* with:
|
||||
\code
|
||||
DTYP = "General Time"
|
||||
INP = "@GETERRCNT"
|
||||
\endcode
|
||||
*
|
||||
* \return Reset error counts
|
||||
**/
|
||||
epicsShareFunc int generalTimeGetErrorCounts(void);
|
||||
|
||||
/**\brief Return the nume of the provider that last returned a valid current time, or
|
||||
* NULL if none.
|
||||
*
|
||||
* Used by stringin device support with:
|
||||
\code
|
||||
DTYP = "General Time"
|
||||
INP = "@BESTTCP"
|
||||
\endcode
|
||||
*
|
||||
* \return Provider name
|
||||
**/
|
||||
epicsShareFunc const char * generalTimeCurrentProviderName(void);
|
||||
|
||||
/**\brief Return the name of the provider that last returned a valid Time Event time, or
|
||||
* NULL of none.
|
||||
*
|
||||
* Used by stringin device support with:
|
||||
\code
|
||||
DTYP = "General Time"
|
||||
INP = "@BESTTEP"
|
||||
\endcode
|
||||
*
|
||||
* \return Provider name
|
||||
**/
|
||||
epicsShareFunc const char * generalTimeEventProviderName(void);
|
||||
|
||||
/**\brief Return the name of the registered current time provider that has the highest
|
||||
* priority.
|
||||
*
|
||||
* Used by stringin device support with:
|
||||
\code
|
||||
DTYP = "General Time"
|
||||
INP = "@TOPTCP"
|
||||
\endcode
|
||||
*
|
||||
* \return Provider name
|
||||
**/
|
||||
epicsShareFunc const char * generalTimeHighestCurrentName(void);
|
||||
|
||||
/* Original names, for compatibility */
|
||||
/** \brief Old name provided for backwards compatibility */
|
||||
#define generalTimeCurrentTpName generalTimeCurrentProviderName
|
||||
/** \brief Old name provided for backwards compatibility */
|
||||
#define generalTimeEventTpName generalTimeEventProviderName
|
||||
|
||||
/**\brief Provide information about the installed providers and their current best times.
|
||||
*
|
||||
* \param interest Desired interest level to report
|
||||
**/
|
||||
epicsShareFunc long generalTimeReport(int interest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author W. Eric Norum
|
||||
* norume@aps.anl.gov
|
||||
* 630 252 4793
|
||||
|
||||
/**
|
||||
* \file epicsMessageQueue.h
|
||||
* \author W. Eric Norum
|
||||
*
|
||||
* \brief A C++ and a C facility for communication between threads.
|
||||
*
|
||||
* Each C function corresponds to one of the C++ methods.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Interthread message passing
|
||||
*/
|
||||
#ifndef epicsMessageQueueh
|
||||
#define epicsMessageQueueh
|
||||
|
||||
@@ -26,22 +27,135 @@ typedef struct epicsMessageQueueOSD *epicsMessageQueueId;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/** Provides methods for sending messages between threads on a first in,
|
||||
* first out basis. It is designed so that a single message queue can
|
||||
* be used with multiple writer and reader threads.
|
||||
*
|
||||
* A C++ epicsMessageQueue cannot be assigned to, copy-constructed, or
|
||||
* constructed without giving the capacity and max-imumMessageSize
|
||||
* arguments.
|
||||
*
|
||||
* The C++ compiler will object to some of the statements below:
|
||||
* \code{.cpp}
|
||||
* epicsMessageQueue mq0(); // Error: default constructor is private
|
||||
* epicsMessageQueue mq1(10, 20); // OK
|
||||
* epicsMessageQueue mq2(t1); // Error: copy constructor is private
|
||||
* epicsMessageQueue*pmq; // OK, pointer
|
||||
* *pmq = mq1; // Error: assignment operator is private
|
||||
* pmq = &mq1; // OK, pointer assignment and address-of
|
||||
* \endcode
|
||||
**/
|
||||
class epicsShareClass epicsMessageQueue {
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Constructor.
|
||||
* \param capacity Maximum number of messages to queue
|
||||
* \param maximumMessageSize Number of bytes of the largest
|
||||
* message that may be queued
|
||||
**/
|
||||
epicsMessageQueue ( unsigned int capacity,
|
||||
unsigned int maximumMessageSize );
|
||||
|
||||
/**
|
||||
* \brief Destructor.
|
||||
**/
|
||||
~epicsMessageQueue ();
|
||||
|
||||
/**
|
||||
* \brief Try to send a message.
|
||||
* \note On VxWorks and RTEMS this method may be called from
|
||||
* an interrupt handler.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if no more messages can be queued or if the message
|
||||
* is larger than the queue's maximum message size.
|
||||
**/
|
||||
int trySend ( void *message, unsigned int messageSize );
|
||||
int send ( void *message, unsigned int messageSize);
|
||||
|
||||
/**
|
||||
* \brief Send a message.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if the message is larger than the queue's maximum
|
||||
* message size.
|
||||
**/
|
||||
int send ( void *message, unsigned int messageSize );
|
||||
|
||||
/**
|
||||
* \brief Send a message or timeout.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if the timeout was reached before the
|
||||
* message could be sent or queued, or if the message is larger
|
||||
* than the queue's maximum message size.
|
||||
**/
|
||||
int send ( void *message, unsigned int messageSize, double timeout );
|
||||
|
||||
/**
|
||||
* \brief Try to receive a message.
|
||||
* If the queue holds at least one message,
|
||||
* the first message on the queue is moved to the specified location
|
||||
* and the length of that message is returned.
|
||||
*
|
||||
* If the received message is larger than the specified message size
|
||||
* the implementation may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if the message queue is empty, or the buffer too small.
|
||||
**/
|
||||
int tryReceive ( void *message, unsigned int size );
|
||||
|
||||
/**
|
||||
* \brief Fetch the next message on the queue.
|
||||
* Wait for a message to be sent if the queue is empty, then move
|
||||
* the first message queued to the specified location.
|
||||
*
|
||||
* If the received message is larger than the specified message size
|
||||
* the implementation may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if the buffer is too small for the message.
|
||||
**/
|
||||
int receive ( void *message, unsigned int size );
|
||||
|
||||
/**
|
||||
* \brief Wait for a message to be queued.
|
||||
* Wait up to \p timeout seconds for a message to be sent if the queue
|
||||
* is empty, then move the first message to the specified location.
|
||||
*
|
||||
* If the received message is larger than the specified
|
||||
* messageBufferSize it may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if a message is not received within the timeout
|
||||
* interval.
|
||||
**/
|
||||
int receive ( void *message, unsigned int size, double timeout );
|
||||
|
||||
/**
|
||||
* \brief Displays some information about the message queue.
|
||||
* \param level Controls the amount of information displayed.
|
||||
**/
|
||||
void show ( unsigned int level = 0 );
|
||||
|
||||
/**
|
||||
* \brief How many messages are queued.
|
||||
* \returns The number of messages presently in the queue.
|
||||
**/
|
||||
unsigned int pending ();
|
||||
|
||||
private: /* Prevent compiler-generated member functions */
|
||||
/* default constructor, copy constructor, assignment operator */
|
||||
private:
|
||||
/**
|
||||
* Prevent compiler-generated member functions default constructor,
|
||||
* copy constructor, assignment operator.
|
||||
**/
|
||||
epicsMessageQueue();
|
||||
epicsMessageQueue(const epicsMessageQueue &);
|
||||
epicsMessageQueue& operator=(const epicsMessageQueue &);
|
||||
@@ -52,39 +166,136 @@ private: /* Prevent compiler-generated member functions */
|
||||
extern "C" {
|
||||
#endif /*__cplusplus */
|
||||
|
||||
/**
|
||||
* \brief Create a message queue.
|
||||
* \param capacity Maximum number of messages to queue
|
||||
* \param maximumMessageSize Number of bytes of the largest
|
||||
* message that may be queued
|
||||
* \return An identifier for the new queue, or 0.
|
||||
**/
|
||||
epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate(
|
||||
unsigned int capacity,
|
||||
unsigned int maximumMessageSize);
|
||||
|
||||
/**
|
||||
* \brief Destroy a message queue, release all its memory.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy(
|
||||
epicsMessageQueueId id);
|
||||
|
||||
/**
|
||||
* \brief Try to send a message.
|
||||
* \note On VxWorks and RTEMS this routine may be called from
|
||||
* an interrupt handler.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if no more messages can be queued or if the message
|
||||
* is larger than the queue's maximum message size.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int messageSize);
|
||||
|
||||
/**
|
||||
* \brief Send a message.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if the message is larger than the queue's maximum
|
||||
* message size.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueSend(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int messageSize);
|
||||
|
||||
/**
|
||||
* \brief Send a message or timeout.
|
||||
* \returns 0 if the message was sent to a receiver or queued for
|
||||
* future delivery.
|
||||
* \returns -1 if the timeout was reached before the
|
||||
* message could be sent or queued, or if the message is larger
|
||||
* than the queue's maximum message size.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int messageSize,
|
||||
double timeout);
|
||||
|
||||
/**
|
||||
* \brief Try to receive a message.
|
||||
*
|
||||
* If the queue holds at least one message,
|
||||
* the first message on the queue is moved to the specified location
|
||||
* and the length of that message is returned.
|
||||
*
|
||||
* If the received message is larger than the specified message size
|
||||
* the implementation may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if the message queue is empty, or the buffer too small.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int size);
|
||||
|
||||
/**
|
||||
* \brief Fetch the next message on the queue.
|
||||
*
|
||||
* Wait for a message to be sent if the queue is empty, then move the
|
||||
* first message queued to the specified location.
|
||||
*
|
||||
* If the received message is larger than the specified message size
|
||||
* the implementation may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if the buffer is too small for the message.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueReceive(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int size);
|
||||
|
||||
/**
|
||||
* \brief Wait for a message to be queued.
|
||||
*
|
||||
* Wait up to \p timeout seconds for a message to be sent if the queue
|
||||
* is empty, then move the first message to the specified location.
|
||||
*
|
||||
* If the received message is larger than the specified message buffer
|
||||
* size the implementation may either return -1, or truncate the
|
||||
* message. It is most efficient if the messageBufferSize is equal
|
||||
* to the maximumMessageSize with which the message queue was
|
||||
* created.
|
||||
* \returns Number of bytes in the message.
|
||||
* \returns -1 if a message is not received within the timeout
|
||||
* interval.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout(
|
||||
epicsMessageQueueId id,
|
||||
void *message,
|
||||
unsigned int size,
|
||||
double timeout);
|
||||
|
||||
/**
|
||||
* \brief How many messages are queued.
|
||||
* \param id Message queue identifier.
|
||||
* \returns The number of messages presently in the queue.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsMessageQueuePending(
|
||||
epicsMessageQueueId id);
|
||||
|
||||
/**
|
||||
* \brief Displays some information about the message queue.
|
||||
* \param id Message queue identifier.
|
||||
* \param level Controls the amount of information displayed.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMessageQueueShow(
|
||||
epicsMessageQueueId id,
|
||||
int level);
|
||||
|
||||
@@ -3,10 +3,34 @@
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* 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.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**\file epicsMutex.h
|
||||
*
|
||||
* \brief APIs for the epicsMutex mutual exclusion semaphore
|
||||
*
|
||||
* Mutual exclusion semaphores are for situations requiring exclusive access to
|
||||
* resources. An epicsMutex may be claimed recursively, i.e. taken more than
|
||||
* once by a thread, which must release it as many times as it was taken.
|
||||
* Recursive usage is common for a set of routines that call each other while
|
||||
* working on an exclusive resource.
|
||||
*
|
||||
* The typical C++ use of a mutual exclusion semaphore is:
|
||||
\code
|
||||
epicsMutex *plock = new epicsMutex;
|
||||
...
|
||||
...
|
||||
plock->lock();
|
||||
// process resources
|
||||
plock->unlock();
|
||||
\endcode
|
||||
*
|
||||
* \note The implementation:
|
||||
* - MUST implement recursive locking
|
||||
* - SHOULD implement priority inheritance and deletion safety if possible.
|
||||
**/
|
||||
#ifndef epicsMutexh
|
||||
#define epicsMutexh
|
||||
|
||||
@@ -14,9 +38,14 @@
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/**\brief An identifier for an epicsMutex for use with the C API */
|
||||
typedef struct epicsMutexParm *epicsMutexId;
|
||||
|
||||
/** Return status from some C API routines. */
|
||||
typedef enum {
|
||||
epicsMutexLockOK,epicsMutexLockTimeout,epicsMutexLockError
|
||||
epicsMutexLockOK = 0,
|
||||
epicsMutexLockTimeout,
|
||||
epicsMutexLockError
|
||||
} epicsMutexLockStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -24,31 +53,82 @@ typedef enum {
|
||||
#include "compilerDependencies.h"
|
||||
#include "epicsGuard.h"
|
||||
|
||||
/**\brief Create a C++ epicsMutex with current filename and line number
|
||||
*/
|
||||
#define newEpicsMutex new epicsMutex(__FILE__,__LINE__)
|
||||
|
||||
/**\brief The C++ API for an epicsMutex.
|
||||
*/
|
||||
class epicsShareClass epicsMutex {
|
||||
public:
|
||||
typedef epicsGuard<epicsMutex> guard_t;
|
||||
typedef epicsGuard<epicsMutex> release_t;
|
||||
class mutexCreateFailed; /* exception payload */
|
||||
class invalidMutex; /* exception payload */
|
||||
|
||||
#if !defined(__GNUC__) || __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<8)
|
||||
/**\brief Create a mutual exclusion semaphore.
|
||||
**/
|
||||
epicsMutex ();
|
||||
|
||||
/**\brief Create a mutual exclusion semaphore with source location.
|
||||
*
|
||||
* \note The newEpicsMutex macro simplifies using this constructor.
|
||||
* \param *pFileName Source file name.
|
||||
* \param lineno Source line number
|
||||
**/
|
||||
epicsMutex ( const char *pFileName, int lineno );
|
||||
#else
|
||||
/**\brief Create a mutual exclusion semaphore.
|
||||
* \param *pFileName Source file name.
|
||||
* \param lineno Source line number
|
||||
**/
|
||||
epicsMutex ( const char *pFileName = __builtin_FILE(), int lineno = __builtin_LINE() );
|
||||
#endif
|
||||
|
||||
/**\brief Delete the semaphore and its resources.
|
||||
**/
|
||||
~epicsMutex ();
|
||||
|
||||
/**\brief Display information about the semaphore.
|
||||
*
|
||||
* \note Results are architecture dependant.
|
||||
*
|
||||
* \param level Desired information level to report
|
||||
**/
|
||||
void show ( unsigned level ) const;
|
||||
void lock (); /* blocks until success */
|
||||
|
||||
/**\brief Claim the semaphore, waiting until it's free if currently owned
|
||||
* owned by a different thread.
|
||||
*
|
||||
* This call blocks until the calling thread can get exclusive access to
|
||||
* the semaphore.
|
||||
* \note After a successful lock(), additional recursive locks may be
|
||||
* issued by the same thread, but each must have an associated unlock().
|
||||
**/
|
||||
void lock ();
|
||||
|
||||
/**\brief Release the semaphore.
|
||||
*
|
||||
* \note If a thread issues recursive locks, it must call unlock() as many
|
||||
* times as it calls lock().
|
||||
**/
|
||||
void unlock ();
|
||||
bool tryLock (); /* true if successful */
|
||||
|
||||
/**\brief Similar to lock() except that the call returns immediately if the
|
||||
* semaphore is currently owned by another thread, giving the value false.
|
||||
*
|
||||
* \return True if the resource is now owned by the caller.
|
||||
* \return False if some other thread already owns the resource.
|
||||
**/
|
||||
bool tryLock ();
|
||||
private:
|
||||
epicsMutexId id;
|
||||
epicsMutex ( const epicsMutex & );
|
||||
epicsMutex & operator = ( const epicsMutex & );
|
||||
};
|
||||
|
||||
/**\brief A semaphore for locating deadlocks in C++ code. */
|
||||
class epicsShareClass epicsDeadlockDetectMutex {
|
||||
public:
|
||||
typedef epicsGuard<epicsDeadlockDetectMutex> guard_t;
|
||||
@@ -74,36 +154,96 @@ private:
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/**\brief Create an epicsMutex semaphore for use from C code.
|
||||
*
|
||||
* This macro stores the source location of the creation call in the mutex.
|
||||
* \return An identifier for the mutex, or NULL if one could not be created.
|
||||
**/
|
||||
#define epicsMutexCreate() epicsMutexOsiCreate(__FILE__,__LINE__)
|
||||
/**\brief Internal API, used by epicsMutexCreate(). */
|
||||
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiCreate(
|
||||
const char *pFileName,int lineno);
|
||||
|
||||
/**\brief Create an epicsMutex semaphore for use from C code.
|
||||
*
|
||||
* This macro stores the source location of the creation call in the mutex.
|
||||
* The routine does not return if the object could not be created.
|
||||
* \return An identifier for the mutex.
|
||||
**/
|
||||
#define epicsMutexMustCreate() epicsMutexOsiMustCreate(__FILE__,__LINE__)
|
||||
/**\brief Internal API, used by epicsMutexMustCreate(). */
|
||||
epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiMustCreate(
|
||||
const char *pFileName,int lineno);
|
||||
|
||||
/**\brief Destroy an epicsMutex semaphore.
|
||||
* \param id The mutex identifier.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMutexDestroy(epicsMutexId id);
|
||||
|
||||
/**\brief Release the semaphore.
|
||||
* \param id The mutex identifier.
|
||||
* \note If a thread issues recursive locks, it must call epicsMutexUnlock()
|
||||
* as many times as it calls epicsMutexLock() or equivalents.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMutexUnlock(epicsMutexId id);
|
||||
|
||||
/**\brief Claim the semaphore, waiting until it's free if currently owned
|
||||
* owned by a different thread.
|
||||
*
|
||||
* This call blocks until the calling thread can get exclusive access to
|
||||
* the semaphore.
|
||||
* \note After a successful lock(), additional recursive locks may be
|
||||
* issued by the same thread, but each must have an associated unlock().
|
||||
* \param id The mutex identifier.
|
||||
* \return Status indicator.
|
||||
**/
|
||||
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock(
|
||||
epicsMutexId id);
|
||||
|
||||
/**\brief Claim a semaphore (see epicsMutexLock()).
|
||||
*
|
||||
* This routine does not return if the identifier is invalid.
|
||||
* \param ID The mutex identifier.
|
||||
**/
|
||||
#define epicsMutexMustLock(ID) { \
|
||||
epicsMutexLockStatus status = epicsMutexLock(ID); \
|
||||
assert(status == epicsMutexLockOK); \
|
||||
}
|
||||
|
||||
/**\brief Similar to epicsMutexLock() except that the call returns immediately,
|
||||
* with the return status indicating if the semaphore is currently owned by
|
||||
* this thread or another thread.
|
||||
*
|
||||
* \return \c epicsMutexLockOK if the resource is now owned by the caller.
|
||||
* \return \c epicsMutexLockTimeout if some other thread owns the resource.
|
||||
**/
|
||||
epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock(
|
||||
epicsMutexId id);
|
||||
|
||||
/**\brief Display information about the semaphore.
|
||||
*
|
||||
* \note Results are architecture dependant.
|
||||
*
|
||||
* \param id The mutex identifier.
|
||||
* \param level Desired information level to report
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMutexShow(
|
||||
epicsMutexId id,unsigned int level);
|
||||
|
||||
/**\brief Display information about all epicsMutex semaphores.
|
||||
*
|
||||
* \note Results are architecture dependant.
|
||||
*
|
||||
* \param onlyLocked Non-zero to show only locked semaphores.
|
||||
* \param level Desired information level to report
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsMutexShowAll(
|
||||
int onlyLocked,unsigned int level);
|
||||
|
||||
/*NOTES:
|
||||
epicsMutex MUST implement recursive locking
|
||||
epicsMutex should implement priority inheritance and deletion safe
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is the interface to the OS dependent
|
||||
* implementation and should NOT be called directly by
|
||||
* user code
|
||||
/**@privatesection
|
||||
* The following are interfaces to the OS dependent
|
||||
* implementation and should NOT be called directly by
|
||||
* user code.
|
||||
*/
|
||||
struct epicsMutexOSD * epicsMutexOsdCreate(void);
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD *);
|
||||
|
||||
@@ -6,6 +6,16 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**
|
||||
* \file epicsReadline.h
|
||||
* \brief Command-line editing functions
|
||||
* \author Eric Norum
|
||||
*
|
||||
* Provides a generalized API for command line history and line-editing.
|
||||
* The implementation of this API can call GNU Readline, libtecla, and on
|
||||
* VxWorks the ledLib routines, according to the EPICS build configuration.
|
||||
*/
|
||||
#ifndef INC_epicsReadline_H
|
||||
#define INC_epicsReadline_H
|
||||
|
||||
@@ -15,9 +25,23 @@ extern "C" {
|
||||
|
||||
#include <shareLib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Create a command-line context
|
||||
* \param in Filehandle to read from
|
||||
* \return Command-line context
|
||||
*/
|
||||
epicsShareFunc void * epicsShareAPI epicsReadlineBegin (FILE *in);
|
||||
/**
|
||||
* \brief Read a line of input
|
||||
* \param prompt Prompt string
|
||||
* \param context To read from
|
||||
* \return Line read
|
||||
*/
|
||||
epicsShareFunc char * epicsShareAPI epicsReadline (const char *prompt, void *context);
|
||||
/**
|
||||
* \brief Destroy a command-line context
|
||||
* \param context Command-line context to destroy
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsReadlineEnd (void *context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -16,30 +16,33 @@ extern "C" {
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/*
|
||||
/** \file epicsSignal.h
|
||||
* \brief OS-independent routines for ignoring Posix signals
|
||||
*
|
||||
* The requests in this interface are typically ignored on OS that do not implement
|
||||
* POSIX signals.
|
||||
*/
|
||||
|
||||
struct epicsThreadOSD;
|
||||
|
||||
/*
|
||||
/** Ignore the SIGHUP signal.
|
||||
* Required to avoid problems with soft IOCs getting SIGHUPs when a
|
||||
* Channel Access client disconnects
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void );
|
||||
|
||||
/*
|
||||
/** Ignore the SIGPIPE signal.
|
||||
* Required to avoid terminating a process which is blocking in a
|
||||
* socket send() call when the SIGPIPE signal is generated by the OS.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void );
|
||||
|
||||
/*
|
||||
* required only if shutdown() and close() do not interrupt a thread blocking in
|
||||
/** Ignore the SIGALRM signal.
|
||||
* Required only if shutdown() and close() do not interrupt a thread blocking in
|
||||
* a socket system call
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void );
|
||||
/** Raise a SIGALRM signal to a specific epicsThread */
|
||||
epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* epicsTempFile.h */
|
||||
/**
|
||||
* \file epicsTempFile.h
|
||||
* \brief OS-independent way to create temporary files.
|
||||
**/
|
||||
|
||||
#ifndef INC_epicsTempFile_H
|
||||
#define INC_epicsTempFile_H
|
||||
@@ -20,6 +23,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Create and open a temporary file.
|
||||
* \return NULL or a FILE pointer to a temporary file.
|
||||
**/
|
||||
epicsShareFunc FILE * epicsShareAPI epicsTempFile(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -5,8 +5,53 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* Copyright (c) 2013 ITER Organization.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**
|
||||
* \file epicsThread.h
|
||||
*
|
||||
* \brief C++ and C descriptions for a thread.
|
||||
*
|
||||
* The epicsThread API is meant as a somewhat minimal interface for
|
||||
* multithreaded applications. It can be implementedon a wide variety of
|
||||
* systems with the restriction that the system MUST support a
|
||||
* multithreaded environment.
|
||||
* A POSIX pthreads version is provided.
|
||||
*
|
||||
* The interface provides the following thread facilities,
|
||||
* with restrictions as noted:
|
||||
* - Life cycle: a thread starts life as a result of a call to
|
||||
* epicsThreadCreate. It terminates when the thread function returns.
|
||||
* It should not return until it has released all resources it uses.
|
||||
* If a thread is expected to terminate as a natural part of its life
|
||||
* cycle then the thread function must return.
|
||||
* - epicsThreadOnce: this provides the ability to have an
|
||||
* initialization function that is guaranteed to be called exactly
|
||||
* once.
|
||||
* - main: if a main routine finishes its work but wants to leave other
|
||||
* threads running it can call epicsThreadExitMain, which should be
|
||||
* the last statement in main.
|
||||
* - Priorities: ranges between 0 and 99 with a higher number meaning
|
||||
* higher priority. A number of constants are defined for iocCore
|
||||
* specific threads. The underlying implementation may collapse the
|
||||
* range 0 to 99 into a smaller range; even a single priority. User
|
||||
* code should never rely on the existence of multiple thread
|
||||
* priorities to guarantee correct behavior.
|
||||
* - Stack Size: epicsThreadCreate accepts a stack size parameter. Three
|
||||
* generic sizes are available: small, medium,and large. Portable code
|
||||
* should always use one of the generic sizes. Some implementation may
|
||||
* ignore the stack size request and use a system default instead.
|
||||
* Virtual memory systems providing generous stack sizes can be
|
||||
* expected to use the system default.
|
||||
* - epicsThreadId: every epicsThread has an Id which gets returned by
|
||||
* epicsThreadCreate and is valid as long as that thread still exists.
|
||||
* A value of 0 always means no thread. If a threadId is used after
|
||||
* the thread has terminated,the results are not defined (but will
|
||||
* normally lead to bad things happening). Thus code that looks after
|
||||
* other threads MUST be aware of threads terminating.
|
||||
*/
|
||||
|
||||
#ifndef epicsThreadh
|
||||
#define epicsThreadh
|
||||
|
||||
@@ -20,6 +65,9 @@ extern "C" {
|
||||
|
||||
typedef void (*EPICSTHREADFUNC)(void *parm);
|
||||
|
||||
/** @name Some Named Thread Priorities
|
||||
* @{
|
||||
*/
|
||||
#define epicsThreadPriorityMax 99
|
||||
#define epicsThreadPriorityMin 0
|
||||
|
||||
@@ -35,8 +83,9 @@ typedef void (*EPICSTHREADFUNC)(void *parm);
|
||||
#define epicsThreadPriorityScanHigh 70
|
||||
#define epicsThreadPriorityIocsh 91
|
||||
#define epicsThreadPriorityBaseMax 91
|
||||
/** @} */
|
||||
|
||||
/* stack sizes for each stackSizeClass are implementation and CPU dependent */
|
||||
/** Stack sizes for each stackSizeClass are implementation and CPU dependent. */
|
||||
typedef enum {
|
||||
epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig
|
||||
} epicsThreadStackSizeClass;
|
||||
@@ -45,11 +94,15 @@ typedef enum {
|
||||
epicsThreadBooleanStatusFail, epicsThreadBooleanStatusSuccess
|
||||
} epicsThreadBooleanStatus;
|
||||
|
||||
/** Lookup target specific default stack size */
|
||||
/**
|
||||
* Get a stack size value that can be given to epicsThreadCreate().
|
||||
* \param size one of the values epicsThreadStackSmall,
|
||||
* epicsThreadStackMedium or epicsThreadStackBig.
|
||||
**/
|
||||
epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize(
|
||||
epicsThreadStackSizeClass size);
|
||||
|
||||
/* (epicsThreadId)0 is guaranteed to be an invalid thread id */
|
||||
/** (epicsThreadId)0 is guaranteed to be an invalid thread id */
|
||||
typedef struct epicsThreadOSD *epicsThreadId;
|
||||
|
||||
typedef epicsThreadId epicsThreadOnceId;
|
||||
@@ -57,27 +110,38 @@ typedef epicsThreadId epicsThreadOnceId;
|
||||
|
||||
/** Perform one-time initialization.
|
||||
*
|
||||
* Run the provided function if it has not run, and is not running.
|
||||
* Run the provided function if it has not run, and is not running in
|
||||
* some other thread.
|
||||
*
|
||||
* @post The provided function has been run.
|
||||
* For each unique epicsThreadOnceId, epicsThreadOnce guarantees that
|
||||
* -# myInitFunc will only be called only once.
|
||||
* -# myInitFunc will have returned before any other epicsThreadOnce
|
||||
* call using the same epicsThreadOnceId returns.
|
||||
*
|
||||
* @code
|
||||
* \code
|
||||
* static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
|
||||
* static void myInitFunc(void *arg) { ... }
|
||||
* static void some Function(void) {
|
||||
* epicsThreadOnce(&onceId, &myInitFunc, NULL);
|
||||
* }
|
||||
* @endcode
|
||||
* \endcode
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadOnce(
|
||||
epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg);
|
||||
|
||||
/* When real-time scheduling is active, attempt any post-init operations
|
||||
/**
|
||||
* When real-time scheduling is active, attempt any post-init operations
|
||||
* that preserve real-time performance. For POSIX targets this locks the
|
||||
* process into RAM, preventing swap-related VM faults.
|
||||
*/
|
||||
**/
|
||||
epicsShareFunc void epicsThreadRealtimeLock(void);
|
||||
|
||||
/**
|
||||
* If the main routine is done but wants to let other threads run it can
|
||||
* call this routine. This should be the last call in main, except the
|
||||
* final return. On most systems epicsThreadExitMain never returns.This
|
||||
* must only be called by the main thread.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadExitMain(void);
|
||||
|
||||
/** For use with epicsThreadCreateOpt() */
|
||||
@@ -103,12 +167,12 @@ typedef struct epicsThreadOpts {
|
||||
#define EPICS_THREAD_OPTS_INIT { \
|
||||
epicsThreadPriorityLow, epicsThreadStackMedium, 0}
|
||||
|
||||
/** @brief Allocate and start a new OS thread.
|
||||
* @param name A name describing this thread. Appears in various log and error message.
|
||||
* @param funptr The thread main function.
|
||||
* @param parm Passed to thread main function.
|
||||
* @param opts Modifiers for the new thread, or NULL to use target specific defaults.
|
||||
* @return NULL on error
|
||||
/** \brief Allocate and start a new OS thread.
|
||||
* \param name A name describing this thread. Appears in various log and error message.
|
||||
* \param funptr The thread main function.
|
||||
* \param parm Passed to thread main function.
|
||||
* \param opts Modifiers for the new thread, or NULL to use target specific defaults.
|
||||
* \return NULL on error
|
||||
*/
|
||||
epicsShareFunc epicsThreadId epicsThreadCreateOpt (
|
||||
const char * name,
|
||||
@@ -156,16 +220,20 @@ epicsShareFunc epicsThreadBooleanStatus epicsShareAPI
|
||||
/** Test if two thread IDs actually refer to the same OS thread */
|
||||
epicsShareFunc int epicsShareAPI epicsThreadIsEqual(
|
||||
epicsThreadId id1, epicsThreadId id2);
|
||||
/** Test if thread has been suspended with epicsThreadSuspendSelf() */
|
||||
/** How and why a thread can be suspended is implementation dependent. A
|
||||
* thread calling epicsThreadSuspendSelf() should result in this routine
|
||||
* returning true for that thread, but a thread may also be suspended
|
||||
* for other reasons.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId id);
|
||||
/** @brief Block the calling thread for at least the specified time.
|
||||
* @param seconds Time to wait in seconds. Values <=0 blocks for the shortest possible time.
|
||||
/** \brief Block the calling thread for at least the specified time.
|
||||
* \param seconds Time to wait in seconds. Values <=0 blocks for the shortest possible time.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds);
|
||||
/** @brief Query a value approximating the OS timer/scheduler resolution.
|
||||
* @return A value in seconds >=0
|
||||
/** \brief Query a value approximating the OS timer/scheduler resolution.
|
||||
* \return A value in seconds >=0
|
||||
*
|
||||
* @warning On targets other than vxWorks and RTEMS, the quantum value often isn't
|
||||
* \warning On targets other than vxWorks and RTEMS, the quantum value often isn't
|
||||
* meaningful. Use of this function is discouraged in portable code.
|
||||
*/
|
||||
epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum(void);
|
||||
@@ -174,23 +242,23 @@ epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum(void);
|
||||
*/
|
||||
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void);
|
||||
/** Attempt to find the first instance of a thread by name.
|
||||
* @return An epicsThreadId, or NULL if no such thread is currently running.
|
||||
* \return An epicsThreadId, or NULL if no such thread is currently running.
|
||||
* Note that a non-NULL ID may still be invalid if this call races
|
||||
* with thread exit.
|
||||
*
|
||||
* @warning Safe use of this function requires external knowledge that this
|
||||
* \warning Safe use of this function requires external knowledge that this
|
||||
* thread will not return.
|
||||
*/
|
||||
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name);
|
||||
/** Return a value approximating the number of threads which this target
|
||||
* can run in parallel. This value is advisory.
|
||||
* @return >=1
|
||||
* \return >=1
|
||||
*/
|
||||
epicsShareFunc int epicsThreadGetCPUs(void);
|
||||
|
||||
/** Return the name of the current thread.
|
||||
*
|
||||
* @return Never NULL. Storage lifetime tied to epicsThreadId.
|
||||
* \return Never NULL. Storage lifetime tied to epicsThreadId.
|
||||
*
|
||||
* This is either a copy of the string passed to epicsThread*Create*(),
|
||||
* or an arbitrary unique string for non-EPICS threads.
|
||||
@@ -206,22 +274,54 @@ epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf(void);
|
||||
epicsShareFunc void epicsShareAPI epicsThreadGetName(
|
||||
epicsThreadId id, char *name, size_t size);
|
||||
|
||||
/**
|
||||
* Is it OK for a thread to block? This can be called by support code
|
||||
* that does not know if it is called in a thread that should not block.
|
||||
* For example the errlog system calls this to decide when messages
|
||||
* should be displayed on the console.
|
||||
**/
|
||||
epicsShareFunc int epicsShareAPI epicsThreadIsOkToBlock(void);
|
||||
/**
|
||||
* When a thread is started the default is that it is not allowed to
|
||||
* block. This method can be called to change the state. For example
|
||||
* iocsh calls this to specify that it is OK to block.
|
||||
**/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock);
|
||||
|
||||
/** Print to stdout information about all running EPICS threads.
|
||||
* @param level 0 prints minimal output. Higher values print more details.
|
||||
* \param level 0 prints minimal output. Higher values print more details.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level);
|
||||
/** Print info about a single EPICS thread. */
|
||||
epicsShareFunc void epicsShareAPI epicsThreadShow(
|
||||
epicsThreadId id,unsigned int level);
|
||||
|
||||
/* Hooks called when a thread starts, map function called once for every thread */
|
||||
/**
|
||||
* Hooks called when a thread starts, map function called once for every thread.
|
||||
**/
|
||||
typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id);
|
||||
|
||||
/**
|
||||
* Register a routine to be called by every new thread before the thread
|
||||
* function gets run. Hook routines will often register a thread exit
|
||||
* routine with epicsAtThreadExit() to release thread-specific resources
|
||||
* they have allocated.
|
||||
*/
|
||||
epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook);
|
||||
|
||||
/**
|
||||
* Remove routine from the list of hooks run at thread creation time.
|
||||
**/
|
||||
epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook);
|
||||
|
||||
/**
|
||||
* Print the current list of hook function pointers.
|
||||
**/
|
||||
epicsShareFunc void epicsThreadHooksShow(void);
|
||||
|
||||
/**
|
||||
* Call func once for every known thread.
|
||||
**/
|
||||
epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func);
|
||||
|
||||
/** Thread local storage */
|
||||
@@ -260,18 +360,18 @@ public:
|
||||
|
||||
extern "C" void epicsThreadCallEntryPoint ( void * );
|
||||
|
||||
/** @brief An OS thread
|
||||
/** \brief An OS thread
|
||||
*
|
||||
* A wrapper around the epicsThread* C API.
|
||||
*
|
||||
* @note Threads must be start() ed.
|
||||
* \note Threads must be start() ed.
|
||||
*/
|
||||
class epicsShareClass epicsThread {
|
||||
public:
|
||||
/** Create a new thread with the provided information.
|
||||
*
|
||||
* cf. epicsThreadOpts
|
||||
* @note Threads must be start() ed.
|
||||
* \note Threads must be start() ed.
|
||||
* @throws epicsThread::unableToCreateThread on error.
|
||||
*/
|
||||
epicsThread ( epicsThreadRunable &,const char *name, unsigned int stackSize,
|
||||
@@ -282,11 +382,11 @@ public:
|
||||
//! Wait for the thread epicsRunnable::run() to return.
|
||||
void exitWait () throw ();
|
||||
//! Wait for the thread epicsRunnable::run() to return.
|
||||
//! @param delay Wait up to this many seconds.
|
||||
//! @returns true if run() returned. false on timeout.
|
||||
//! \param delay Wait up to this many seconds.
|
||||
//! \return true if run() returned. false on timeout.
|
||||
bool exitWait ( const double delay ) throw ();
|
||||
//! @throws A special exitException which will be caught and ignored.
|
||||
//! @note This exitException doesn't not derive from std::exception
|
||||
//! \note This exitException doesn't not derive from std::exception
|
||||
static void exit ();
|
||||
//! cf. epicsThreadResume()
|
||||
void resume () throw ();
|
||||
@@ -300,7 +400,7 @@ public:
|
||||
void setPriority ( unsigned int ) throw ();
|
||||
bool priorityIsEqual ( const epicsThread & ) const throw ();
|
||||
bool isSuspended () const throw ();
|
||||
//! @return true if call through this thread's epicsRunnable::run()
|
||||
//! \return true if call through this thread's epicsRunnable::run()
|
||||
bool isCurrentThread () const throw ();
|
||||
bool operator == ( const epicsThread & ) const throw ();
|
||||
//! Say something interesting about this thread to stdout.
|
||||
@@ -331,7 +431,7 @@ private:
|
||||
epicsThread ( const epicsThread & );
|
||||
epicsThread & operator = ( const epicsThread & );
|
||||
friend void epicsThreadCallEntryPoint ( void * );
|
||||
void printLastChanceExceptionMessage (
|
||||
void printLastChanceExceptionMessage (
|
||||
const char * pExceptionTypeName,
|
||||
const char * pExceptionContext );
|
||||
/* exceptions */
|
||||
@@ -346,7 +446,7 @@ protected:
|
||||
};
|
||||
|
||||
template < class T >
|
||||
class epicsThreadPrivate :
|
||||
class epicsThreadPrivate :
|
||||
private epicsThreadPrivateBase {
|
||||
public:
|
||||
epicsThreadPrivate ();
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* epicsTime.h */
|
||||
/* Author Jeffrey O. Hill */
|
||||
/** \file epicsTime.h
|
||||
* \brief EPICS time-stamps (epicsTimeStamp), epicsTime C++ class
|
||||
* and C functions for handling wall-clock times.
|
||||
* \author Jeffrey O. Hill
|
||||
*/
|
||||
|
||||
#ifndef epicsTimehInclude
|
||||
#define epicsTimehInclude
|
||||
@@ -19,139 +22,294 @@
|
||||
#include "osdTime.h"
|
||||
#include "errMdef.h"
|
||||
|
||||
/* The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC */
|
||||
/** \brief The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC */
|
||||
#define POSIX_TIME_AT_EPICS_EPOCH 631152000u
|
||||
|
||||
/* epics time stamp for C interface*/
|
||||
/** \brief EPICS time stamp, for use from C code.
|
||||
*
|
||||
* Because it uses an unsigned 32-bit integer to hold the seconds count, an
|
||||
* epicsTimeStamp can safely represent time stamps until the year 2106.
|
||||
*/
|
||||
typedef struct epicsTimeStamp {
|
||||
epicsUInt32 secPastEpoch; /* seconds since 0000 Jan 1, 1990 */
|
||||
epicsUInt32 nsec; /* nanoseconds within second */
|
||||
epicsUInt32 secPastEpoch; /**< \brief seconds since 0000 Jan 1, 1990 */
|
||||
epicsUInt32 nsec; /**< \brief nanoseconds within second */
|
||||
} epicsTimeStamp;
|
||||
|
||||
/*TS_STAMP is deprecated */
|
||||
/** \brief Old time-stamp data type, deprecated.
|
||||
* \deprecated TS_STAMP was provided for compatibility with Base-3.13 code.
|
||||
* It will be removed in some future release of EPICS 7.
|
||||
*/
|
||||
#define TS_STAMP epicsTimeStamp
|
||||
|
||||
|
||||
/** \struct timespec
|
||||
* \brief Defined by POSIX Real Time
|
||||
*
|
||||
* This is defined by POSIX Real Time. It requires two mandatory fields:
|
||||
* \li <tt>time_t tv_sec</tt> - Number of seconds since 1970 (The POSIX epoch)
|
||||
* \li <tt>long tv_nsec</tt> - nanoseconds within a second
|
||||
*/
|
||||
struct timespec; /* POSIX real time */
|
||||
|
||||
/** \struct timeval
|
||||
* \brief BSD and SRV5 Unix timestamp
|
||||
*
|
||||
* BSD and SRV5 Unix timestamp. It has two fields:
|
||||
* \li <tt>time_t tv_sec</tt> - Number of seconds since 1970 (The POSIX epoch)
|
||||
* \li <tt>time_t tv_nsec</tt> - nanoseconds within a second
|
||||
*/
|
||||
struct timeval; /* BSD */
|
||||
|
||||
/** \struct l_fp
|
||||
* \brief Network Time Protocol timestamp
|
||||
*
|
||||
* Network Time Protocol timestamp. The fields are:
|
||||
* \li \c lui - Number of seconds since 1900 (The NTP epoch)
|
||||
* \li \c luf - Fraction of a second. For example 0x800000000 represents 1/2 second.
|
||||
*/
|
||||
struct l_fp; /* NTP timestamp */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* extend ANSI C RTL "struct tm" to include nano seconds within a second
|
||||
* and a struct tm that is adjusted for the local timezone
|
||||
/** \brief C++ only ANSI C <tt>struct tm</tt> with nanoseconds, local timezone
|
||||
*
|
||||
* Extend ANSI C "struct tm" to include nano seconds within a second
|
||||
* and a struct tm that is adjusted for the local timezone.
|
||||
*/
|
||||
struct local_tm_nano_sec {
|
||||
struct tm ansi_tm; /* ANSI C time details */
|
||||
unsigned long nSec; /* nano seconds extension */
|
||||
struct tm ansi_tm; /**< \brief ANSI C time details */
|
||||
unsigned long nSec; /**< \brief nanoseconds extension */
|
||||
};
|
||||
|
||||
/*
|
||||
* extend ANSI C RTL "struct tm" to includes nano seconds within a second
|
||||
* and a struct tm that is adjusted for GMT (UTC)
|
||||
/** \brief C++ only ANSI C <tt>sruct tm</tt> with nanoseconds, UTC
|
||||
*
|
||||
* Extend ANSI C "struct tm" to include nanoseconds within a second
|
||||
* and a struct tm that is adjusted for GMT (UTC).
|
||||
*/
|
||||
struct gm_tm_nano_sec {
|
||||
struct tm ansi_tm; /* ANSI C time details */
|
||||
unsigned long nSec; /* nano seconds extension */
|
||||
struct tm ansi_tm; /**< \brief ANSI C time details */
|
||||
unsigned long nSec; /**< \brief nanoseconds extension */
|
||||
};
|
||||
|
||||
/*
|
||||
* wrapping this in a struct allows conversion to and
|
||||
* from ANSI time_t but does not allow unexpected
|
||||
* conversions to occur
|
||||
/** \brief C++ only ANSI C time_t
|
||||
*
|
||||
* This is for converting to/from the ANSI C \c time_t. Since \c time_t
|
||||
* is usually an elementary type providing a conversion operator from
|
||||
* \c time_t to/from epicsTime could cause undesirable implicit
|
||||
* conversions. Providing a conversion operator to/from the
|
||||
* \c time_t_wrapper instead prevents implicit conversions.
|
||||
*/
|
||||
struct time_t_wrapper {
|
||||
time_t ts;
|
||||
};
|
||||
|
||||
/** \brief C++ Event number wrapper class
|
||||
*
|
||||
* Stores an event number for use by the epicsTime::getEvent() static
|
||||
* class method.
|
||||
*/
|
||||
class epicsShareClass epicsTimeEvent
|
||||
{
|
||||
public:
|
||||
epicsTimeEvent (const int &number);
|
||||
operator int () const;
|
||||
epicsTimeEvent (const int &number); /**< \brief Constructor */
|
||||
operator int () const; /**< \brief Extractor */
|
||||
private:
|
||||
int eventNumber;
|
||||
};
|
||||
|
||||
|
||||
/** \brief C++ time stamp object
|
||||
*
|
||||
* Holds an EPICS time stamp, and provides conversion functions for both
|
||||
* input and output from/to other types.
|
||||
*
|
||||
* \note Time conversions: The epicsTime implementation will properly
|
||||
* convert between the various formats from the beginning of the EPICS
|
||||
* epoch until at least 2038. Unless the underlying architecture support
|
||||
* has defective POSIX, BSD/SRV5, or standard C time support the EPICS
|
||||
* implementation should be valid until 2106.
|
||||
*/
|
||||
class epicsShareClass epicsTime
|
||||
{
|
||||
public:
|
||||
/* exceptions */
|
||||
/// \brief Exception: Time provider problem
|
||||
class unableToFetchCurrentTime {};
|
||||
/// \brief Exception: Bad field(s) in <tt>struct tm</tt>
|
||||
class formatProblemWithStructTM {};
|
||||
|
||||
/** \brief The default constructor sets the time to the EPICS epoch. */
|
||||
epicsTime ();
|
||||
|
||||
/** \brief Get time of event system event.
|
||||
*
|
||||
* Returns an epicsTime indicating when the associated event system
|
||||
* event last occurred.
|
||||
*/
|
||||
static epicsTime getEvent ( const epicsTimeEvent & );
|
||||
/** \brief Get current clock time
|
||||
*
|
||||
* Returns an epicsTime containing the current time. For example:
|
||||
* \code{.cpp}
|
||||
* epicsTime now = epicsTime::getCurrent();
|
||||
* \endcode
|
||||
*/
|
||||
static epicsTime getCurrent ();
|
||||
/** \brief Get current monotonic time
|
||||
*
|
||||
* Returns an epicsTime containing the current monotonic time, a
|
||||
* high-resolution OS clock that counts at a steady rate, never
|
||||
* going backwards or jumping forwards. This time is only useful
|
||||
* for measuring time differences.
|
||||
*/
|
||||
static epicsTime getMonotonic ();
|
||||
|
||||
/* convert to and from EPICS epicsTimeStamp format */
|
||||
/** \name epicsTimeStamp conversions
|
||||
* Convert to and from EPICS epicsTimeStamp format
|
||||
* @{ */
|
||||
/** \brief Convert to epicsTimeStamp */
|
||||
operator epicsTimeStamp () const;
|
||||
/** \brief Construct from epicsTimeStamp */
|
||||
epicsTime ( const epicsTimeStamp & ts );
|
||||
/** \brief Assign from epicsTimeStamp */
|
||||
epicsTime & operator = ( const epicsTimeStamp & );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from ANSI time_t */
|
||||
/** \name ANSI C time_t conversions
|
||||
* Convert to and from ANSI C \c time_t wrapper .
|
||||
* @{ */
|
||||
/** \brief Convert to ANSI C \c time_t */
|
||||
operator time_t_wrapper () const;
|
||||
/** \brief Construct from ANSI C \c time_t */
|
||||
epicsTime ( const time_t_wrapper & );
|
||||
/** \brief Assign from ANSI C \c time_t */
|
||||
epicsTime & operator = ( const time_t_wrapper & );
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* convert to and from ANSI Cs "struct tm" (with nano seconds)
|
||||
* adjusted for the local time zone
|
||||
*/
|
||||
/** \name ANSI C struct tm local-time conversions
|
||||
* Convert to and from ANSI Cs <tt>struct tm</tt> (with nano seconds),
|
||||
* adjusted for the local time zone.
|
||||
* @{ */
|
||||
/** \brief Convert to <tt>struct tm</tt> in local time zone */
|
||||
operator local_tm_nano_sec () const;
|
||||
/** \brief Construct from <tt>struct tm</tt> in local time zone */
|
||||
epicsTime ( const local_tm_nano_sec & );
|
||||
/** \brief Assign from <tt>struct tm</tt> in local time zone */
|
||||
epicsTime & operator = ( const local_tm_nano_sec & );
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* convert to and from ANSI Cs "struct tm" (with nano seconds)
|
||||
* adjusted for GM time (UTC)
|
||||
*/
|
||||
/** \name ANSI C struct tm UTC conversions
|
||||
* Convert to and from ANSI Cs <tt>struct tm</tt> (with nano seconds),
|
||||
* adjusted for Greenwich Mean Time (UTC).
|
||||
* @{ */
|
||||
/** \brief Convert to <tt>struct tm</tt> in UTC/GMT */
|
||||
operator gm_tm_nano_sec () const;
|
||||
/** \brief Construct from <tt>struct tm</tt> in UTC/GMT */
|
||||
epicsTime ( const gm_tm_nano_sec & );
|
||||
/** \brief Assign from <tt>struct tm</tt> in UTC */
|
||||
epicsTime & operator = ( const gm_tm_nano_sec & );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from POSIX RTs "struct timespec" */
|
||||
/** \name POSIX RT struct timespec conversions
|
||||
* Convert to and from the POSIX RealTime <tt>struct timespec</tt>
|
||||
* format.
|
||||
* @{ */
|
||||
/** \brief Convert to <tt>struct timespec</tt> */
|
||||
operator struct timespec () const;
|
||||
/** \brief Construct from <tt>struct timespec</tt> */
|
||||
epicsTime ( const struct timespec & );
|
||||
/** \brief Assign from <tt>struct timespec</tt> */
|
||||
epicsTime & operator = ( const struct timespec & );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from BSDs "struct timeval" */
|
||||
/** \name BSD's struct timeval conversions
|
||||
* Convert to and from the BSD <tt>struct timeval</tt> format.
|
||||
* @{ */
|
||||
/** \brief Convert to <tt>struct timeval</tt> */
|
||||
operator struct timeval () const;
|
||||
/** \brief Construct from <tt>struct timeval</tt> */
|
||||
epicsTime ( const struct timeval & );
|
||||
/** \brief Assign from <tt>struct timeval</tt> */
|
||||
epicsTime & operator = ( const struct timeval & );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from NTP timestamp format */
|
||||
/** \name NTP timestamp conversions
|
||||
* Convert to and from the NTP timestamp structure \c l_fp
|
||||
* @{ */
|
||||
/** \brief Convert to NTP format */
|
||||
operator l_fp () const;
|
||||
/** \brief Construct from NTP format */
|
||||
epicsTime ( const l_fp & );
|
||||
/** \brief Assign from NTP format */
|
||||
epicsTime & operator = ( const l_fp & );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from WIN32s FILETIME (implemented only on WIN32) */
|
||||
/** \name WIN32 FILETIME conversions
|
||||
* Convert to and from WIN32s <tt> _FILETIME</tt>
|
||||
* \note These are only implemented on Windows targets.
|
||||
* @{ */
|
||||
/** \brief Convert to Windows <tt>struct _FILETIME</tt> */
|
||||
operator struct _FILETIME () const;
|
||||
/** \brief Constuct from Windows <tt>struct _FILETIME</tt> */
|
||||
epicsTime ( const struct _FILETIME & );
|
||||
/** \brief Assign from Windows <tt>struct _FILETIME</tt> */
|
||||
epicsTime & operator = ( const struct _FILETIME & );
|
||||
/** @} */
|
||||
|
||||
/* arithmetic operators */
|
||||
double operator- ( const epicsTime & ) const; /* returns seconds */
|
||||
epicsTime operator+ ( const double & ) const; /* add rhs seconds */
|
||||
epicsTime operator- ( const double & ) const; /* subtract rhs seconds */
|
||||
epicsTime operator+= ( const double & ); /* add rhs seconds */
|
||||
epicsTime operator-= ( const double & ); /* subtract rhs seconds */
|
||||
/** \name Arithmetic operators
|
||||
* Standard operators involving epicsTime objects and time differences
|
||||
* which are always expressed as a \c double in seconds.
|
||||
* @{ */
|
||||
/// \brief \p lhs minus \p rhs, in seconds
|
||||
double operator- ( const epicsTime & ) const;
|
||||
/// \brief \p lhs plus rhs seconds
|
||||
epicsTime operator+ ( const double & ) const;
|
||||
/// \brief \p lhs minus rhs seconds
|
||||
epicsTime operator- ( const double & ) const;
|
||||
/// \brief add rhs seconds to \p lhs
|
||||
epicsTime operator+= ( const double & );
|
||||
/// \brief subtract rhs seconds from \p lhs
|
||||
epicsTime operator-= ( const double & );
|
||||
/** @} */
|
||||
|
||||
/* comparison operators */
|
||||
bool operator == ( const epicsTime & ) const;
|
||||
bool operator != ( const epicsTime & ) const;
|
||||
bool operator <= ( const epicsTime & ) const;
|
||||
bool operator < ( const epicsTime & ) const;
|
||||
bool operator >= ( const epicsTime & ) const;
|
||||
bool operator > ( const epicsTime & ) const;
|
||||
/** \name Comparison operators
|
||||
* Standard comparisons between epicsTime objects.
|
||||
* @{ */
|
||||
/// \brief \p lhs equals \p rhs
|
||||
bool operator == ( const epicsTime & ) const;
|
||||
/// \brief \p lhs not equal to \p rhs
|
||||
bool operator != ( const epicsTime & ) const;
|
||||
/// \brief \p rhs no later than \p lhs
|
||||
bool operator <= ( const epicsTime & ) const;
|
||||
/// \brief \p lhs was before \p rhs
|
||||
bool operator < ( const epicsTime & ) const;
|
||||
/// \brief \p rhs not before \p lhs
|
||||
bool operator >= ( const epicsTime & ) const;
|
||||
/// \brief \p lhs was after \p rhs
|
||||
bool operator > ( const epicsTime & ) const;
|
||||
/** @} */
|
||||
|
||||
/* convert current state to user-specified string */
|
||||
/** \brief Convert to string in user-specified format
|
||||
*
|
||||
* This method extends the standard C library routine strftime().
|
||||
* See your OS documentation for details about the standard routine.
|
||||
* The epicsTime method adds support for printing the fractional
|
||||
* portion of the time. It searches the format string for the
|
||||
* sequence <tt>%0<i>n</i>f</tt> where \a n is the desired precision,
|
||||
* and uses this format to convert the fractional seconds with the
|
||||
* requested precision. For example:
|
||||
* \code{.cpp}
|
||||
* epicsTime time = epicsTime::getCurrent();
|
||||
* char buf[30];
|
||||
* time.strftime(buf, 30, "%Y-%m-%d %H:%M:%S.%06f");
|
||||
* printf("%s\n", buf);
|
||||
* \endcode
|
||||
* This will print the current time in the format:
|
||||
* \code
|
||||
* 2001-01-26 20:50:29.813505
|
||||
* \endcode
|
||||
*/
|
||||
size_t strftime ( char * pBuff, size_t bufLength, const char * pFormat ) const;
|
||||
|
||||
/* dump current state to standard out */
|
||||
/** \brief Dump current state to standard out */
|
||||
void show ( unsigned interestLevel ) const;
|
||||
|
||||
private:
|
||||
@@ -173,98 +331,179 @@ private:
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* epicsTime routines return S_time_ error status values */
|
||||
/** \name Return status values
|
||||
* epicsTime routines return \c S_time_ error status values:
|
||||
* @{
|
||||
*/
|
||||
/** \brief Success */
|
||||
#define epicsTimeOK 0
|
||||
/** \brief No time provider */
|
||||
#define S_time_noProvider (M_time| 1) /*No time provider*/
|
||||
/** \brief Bad event number */
|
||||
#define S_time_badEvent (M_time| 2) /*Bad event number*/
|
||||
/** \brief Invalid arguments */
|
||||
#define S_time_badArgs (M_time| 3) /*Invalid arguments*/
|
||||
/** \brief Out of memory */
|
||||
#define S_time_noMemory (M_time| 4) /*Out of memory*/
|
||||
/** \brief Provider not synchronized */
|
||||
#define S_time_unsynchronized (M_time| 5) /*Provider not synchronized*/
|
||||
#define S_time_timezone (M_time| 6) /*Invalid timeone*/
|
||||
/** \brief Invalid timezone */
|
||||
#define S_time_timezone (M_time| 6) /*Invalid timezone*/
|
||||
/** \brief Time conversion error */
|
||||
#define S_time_conversion (M_time| 7) /*Time conversion error*/
|
||||
/** @} */
|
||||
|
||||
/*Some special values for eventNumber*/
|
||||
/** \name epicsTimeEvent numbers
|
||||
* Some special values for eventNumber:
|
||||
* @{
|
||||
*/
|
||||
#define epicsTimeEventCurrentTime 0
|
||||
#define epicsTimeEventBestTime -1
|
||||
#define epicsTimeEventDeviceTime -2
|
||||
/** @} */
|
||||
|
||||
/* These are implemented in the "generalTime" framework */
|
||||
/** \name generalTime functions
|
||||
* These are implemented in the "generalTime" framework:
|
||||
* @{
|
||||
*/
|
||||
/** \brief Get current time into \p *pDest */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp * pDest );
|
||||
/** \brief Get time of event \p eventNumber into \p *pDest */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGetEvent (
|
||||
epicsTimeStamp *pDest, int eventNumber);
|
||||
/** \brief Get monotonic time into \p *pDest */
|
||||
epicsShareFunc int epicsTimeGetMonotonic ( epicsTimeStamp * pDest );
|
||||
/** @} */
|
||||
|
||||
/* These are callable from an Interrupt Service Routine */
|
||||
/** \name ISR-callable
|
||||
* These routines may be called from an Interrupt Service Routine, and
|
||||
* will return a value from the last current time or event time provider
|
||||
* that sucessfully returned a result from the equivalent non-ISR routine.
|
||||
* @{
|
||||
*/
|
||||
/** \brief Get current time into \p *pDest (ISR-safe) */
|
||||
epicsShareFunc int epicsTimeGetCurrentInt(epicsTimeStamp *pDest);
|
||||
/** \brief Get time of event \p eventNumber into \p *pDest (ISR-safe) */
|
||||
epicsShareFunc int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber);
|
||||
/** @} */
|
||||
|
||||
/* convert to and from ANSI C's "time_t" */
|
||||
/** \name ANSI C time_t conversions
|
||||
* Convert to and from ANSI C \c time_t
|
||||
* @{
|
||||
*/
|
||||
/** \brief Convert epicsTimeStamp to ANSI C \c time_t */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeToTime_t (
|
||||
time_t * pDest, const epicsTimeStamp * pSrc );
|
||||
/** \brief Convert ANSI C \c time_t to epicsTimeStamp */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeFromTime_t (
|
||||
epicsTimeStamp * pDest, time_t src );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from ANSI C's "struct tm" with nano seconds */
|
||||
/** \name ANSI C struct tm conversions
|
||||
* Convert to and from ANSI C's <tt>struct tm</tt> with nanoseconds
|
||||
* @{
|
||||
*/
|
||||
/** \brief Convert epicsTimeStamp to <tt>struct tm</tt> in local time zone */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeToTM (
|
||||
struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc );
|
||||
/** \brief Convert epicsTimeStamp to <tt>struct tm</tt> in UTC/GMT */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeToGMTM (
|
||||
struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc );
|
||||
/** \brief Set epicsTimeStamp from <tt>struct tm</tt> in local time zone */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeFromTM (
|
||||
epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc );
|
||||
/** \brief Set epicsTimeStamp from <tt>struct tm</tt> in UTC/GMT */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeFromGMTM (
|
||||
epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from POSIX RT's "struct timespec" */
|
||||
/** \name POSIX RT struct timespec conversions
|
||||
* Convert to and from the POSIX RealTime <tt>struct timespec</tt>
|
||||
* format.
|
||||
* @{ */
|
||||
/** \brief Convert epicsTimeStamp to <tt>struct timespec</tt> */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeToTimespec (
|
||||
struct timespec * pDest, const epicsTimeStamp * pSrc );
|
||||
/** \brief Set epicsTimeStamp from <tt>struct timespec</tt> */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeFromTimespec (
|
||||
epicsTimeStamp * pDest, const struct timespec * pSrc );
|
||||
/** @} */
|
||||
|
||||
/* convert to and from BSD's "struct timeval" */
|
||||
/** \name BSD's struct timeval conversions
|
||||
* Convert to and from the BSD <tt>struct timeval</tt> format.
|
||||
* @{ */
|
||||
/** \brief Convert epicsTimeStamp to <tt>struct timeval</tt> */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeToTimeval (
|
||||
struct timeval * pDest, const epicsTimeStamp * pSrc );
|
||||
/** \brief Set epicsTimeStamp from <tt>struct timeval</tt> */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeFromTimeval (
|
||||
epicsTimeStamp * pDest, const struct timeval * pSrc );
|
||||
/** @} */
|
||||
|
||||
/*arithmetic operations */
|
||||
/** \name Arithmetic operations
|
||||
* Arithmetic operations on epicsTimeStamp objects and time differences
|
||||
* which are always expressed as a \c double in seconds.
|
||||
* @{ */
|
||||
/** \brief Time difference between \p left and \p right in seconds. */
|
||||
epicsShareFunc double epicsShareAPI epicsTimeDiffInSeconds (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight );/* left - right */
|
||||
/** \brief Add some number of seconds to \p dest */
|
||||
epicsShareFunc void epicsShareAPI epicsTimeAddSeconds (
|
||||
epicsTimeStamp * pDest, double secondsToAdd ); /* adds seconds to *pDest */
|
||||
/** @} */
|
||||
|
||||
/*comparison operations: returns (0,1) if (false,true) */
|
||||
/** \name Comparison operators
|
||||
* Comparisons between epicsTimeStamp objects, returning 0=false, 1=true.
|
||||
* @{ */
|
||||
/** \brief \p left equals \p right */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeEqual (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** \brief \p left not equal to \p right */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeNotEqual (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** \brief \p left was before \p right */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeLessThan (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** \brief \p right was no later than \p left */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeLessThanEqual (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left <= right) */
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** \brief \p left was after \p right */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGreaterThan (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left > right */
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** \brief \p right was not before \p left */
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual (
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left >= right */
|
||||
const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight);
|
||||
/** @} */
|
||||
|
||||
/*convert to ASCII string */
|
||||
/** \brief Convert epicsTimeStamp to string. See epicsTime::strftime() */
|
||||
epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime (
|
||||
char * pBuff, size_t bufLength, const char * pFormat, const epicsTimeStamp * pTS );
|
||||
|
||||
/* dump current state to standard out */
|
||||
/** \brief Dump current state to stdout */
|
||||
epicsShareFunc void epicsShareAPI epicsTimeShow (
|
||||
const epicsTimeStamp *, unsigned interestLevel );
|
||||
|
||||
/* OS dependent reentrant versions of the ANSI C interface because */
|
||||
/* vxWorks gmtime_r interface does not match POSIX standards */
|
||||
/** \name Reentrant time_t to struct tm conversions
|
||||
* OS-specific reentrant versions of the ANSI C interface because the
|
||||
* vxWorks \c gmtime_r interface does not match POSIX standards
|
||||
* @{ */
|
||||
/** \brief Break down a \c time_t into a <tt>struct tm</tt> in the local timezone */
|
||||
epicsShareFunc int epicsShareAPI epicsTime_localtime ( const time_t * clock, struct tm * result );
|
||||
/** \brief Break down a \c time_t into a <tt>struct tm</tt> in the UTC timezone */
|
||||
epicsShareFunc int epicsShareAPI epicsTime_gmtime ( const time_t * clock, struct tm * result );
|
||||
/** @} */
|
||||
|
||||
/* Advertised monotonic counter resolution (may not be accurate).
|
||||
* Minimum non-zero difference between two calls to epicsMonotonicGet()
|
||||
/** \name Monotonic time routines
|
||||
* @{ */
|
||||
/** \brief Monotonic time resolution, may not be accurate. Returns the
|
||||
* minimum non-zero time difference between two calls to epicsMonotonicGet()
|
||||
* in units of nanoseconds.
|
||||
*/
|
||||
epicsShareFunc epicsUInt64 epicsMonotonicResolution(void);
|
||||
/* Fetch monotonic counter, return is nano-seconds since an unspecified time */
|
||||
/** \brief Fetch monotonic counter, returns the number of nanoseconds since
|
||||
* some unspecified time. */
|
||||
epicsShareFunc epicsUInt64 epicsMonotonicGet(void);
|
||||
/** @} */
|
||||
|
||||
#ifdef EPICS_EXPOSE_LIBCOM_MONOTONIC_PRIVATE
|
||||
epicsShareFunc void osdMonotonicInit(void);
|
||||
@@ -366,4 +605,3 @@ inline epicsTime & epicsTime::operator = ( const time_t_wrapper & rhs )
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* epicsTimehInclude */
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ extern "C" {
|
||||
#define OSI_PATH_SEPARATOR "\\"
|
||||
|
||||
/** Return the absolute path of the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
* \return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecName(void);
|
||||
|
||||
/** Return the absolute path of the directory containing the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
* \return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecDir(void);
|
||||
|
||||
@@ -24,13 +24,13 @@ extern "C" {
|
||||
#define OSI_PATH_SEPARATOR "\\"
|
||||
|
||||
/** Return the absolute path of the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
\return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecName(void);
|
||||
|
||||
/** Return the absolute path of the directory containing the current executable.
|
||||
@returns NULL or the path. Caller must free()
|
||||
\return NULL or the path. Caller must free()
|
||||
*/
|
||||
epicsShareFunc
|
||||
char *epicsGetExecDir(void);
|
||||
|
||||
@@ -4,8 +4,14 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Michael Davidsaver <mdavidsaver@bnl.gov>
|
||||
/**
|
||||
* \file epicsMMIODef.h
|
||||
* \brief Memory Mapped I/O
|
||||
*
|
||||
* Definitions related to Memory Mapped I/O
|
||||
*
|
||||
* \author Michael Davidsaver <mdavidsaver@bnl.gov>
|
||||
* @ingroup mmio
|
||||
*/
|
||||
|
||||
#ifndef EPICSMMIODEF_H
|
||||
@@ -26,7 +32,7 @@
|
||||
*@{
|
||||
*/
|
||||
|
||||
/** @brief Read a single byte.
|
||||
/** \brief Read a single byte.
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
epicsUInt8
|
||||
@@ -35,7 +41,7 @@ ioread8(volatile void* addr)
|
||||
return *(volatile epicsUInt8*)(addr);
|
||||
}
|
||||
|
||||
/** @brief Write a single byte.
|
||||
/** \brief Write a single byte.
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
void
|
||||
@@ -44,7 +50,7 @@ iowrite8(volatile void* addr, epicsUInt8 val)
|
||||
*(volatile epicsUInt8*)(addr) = val;
|
||||
}
|
||||
|
||||
/** @brief Read two bytes in host order.
|
||||
/** \brief Read two bytes in host order.
|
||||
* Not byte swapping
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
@@ -54,7 +60,7 @@ nat_ioread16(volatile void* addr)
|
||||
return *(volatile epicsUInt16*)(addr);
|
||||
}
|
||||
|
||||
/** @brief Write two byte in host order.
|
||||
/** \brief Write two byte in host order.
|
||||
* Not byte swapping
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
@@ -64,7 +70,7 @@ nat_iowrite16(volatile void* addr, epicsUInt16 val)
|
||||
*(volatile epicsUInt16*)(addr) = val;
|
||||
}
|
||||
|
||||
/** @brief Read four bytes in host order.
|
||||
/** \brief Read four bytes in host order.
|
||||
* Not byte swapping
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
@@ -74,7 +80,7 @@ nat_ioread32(volatile void* addr)
|
||||
return *(volatile epicsUInt32*)(addr);
|
||||
}
|
||||
|
||||
/** @brief Write four byte in host order.
|
||||
/** \brief Write four byte in host order.
|
||||
* Not byte swapping
|
||||
*/
|
||||
static EPICS_ALWAYS_INLINE
|
||||
@@ -151,50 +157,50 @@ bswap32(epicsUInt32 value)
|
||||
# error Unable to determine native byte order
|
||||
#endif
|
||||
|
||||
/** @def bswap16
|
||||
* @brief Unconditional two byte swap
|
||||
/** \def bswap16
|
||||
* \brief Unconditional two byte swap
|
||||
*/
|
||||
/** @def bswap32
|
||||
* @brief Unconditional four byte swap
|
||||
/** \def bswap32
|
||||
* \brief Unconditional four byte swap
|
||||
*/
|
||||
/** @def be_ioread16
|
||||
* @brief Read two byte in big endian order.
|
||||
/** \def be_ioread16
|
||||
* \brief Read two byte in big endian order.
|
||||
*/
|
||||
/** @def be_iowrite16
|
||||
* @brief Write two byte in big endian order.
|
||||
/** \def be_iowrite16
|
||||
* \brief Write two byte in big endian order.
|
||||
*/
|
||||
/** @def be_ioread32
|
||||
* @brief Read four byte in big endian order.
|
||||
/** \def be_ioread32
|
||||
* \brief Read four byte in big endian order.
|
||||
*/
|
||||
/** @def be_iowrite32
|
||||
* @brief Write four byte in big endian order.
|
||||
/** \def be_iowrite32
|
||||
* \brief Write four byte in big endian order.
|
||||
*/
|
||||
/** @def le_ioread16
|
||||
* @brief Read two byte in little endian order.
|
||||
/** \def le_ioread16
|
||||
* \brief Read two byte in little endian order.
|
||||
*/
|
||||
/** @def le_iowrite16
|
||||
* @brief Write two byte in little endian order.
|
||||
/** \def le_iowrite16
|
||||
* \brief Write two byte in little endian order.
|
||||
*/
|
||||
/** @def le_ioread32
|
||||
* @brief Read four byte in little endian order.
|
||||
/** \def le_ioread32
|
||||
* \brief Read four byte in little endian order.
|
||||
*/
|
||||
/** @def le_iowrite32
|
||||
* @brief Write four byte in little endian order.
|
||||
/** \def le_iowrite32
|
||||
* \brief Write four byte in little endian order.
|
||||
*/
|
||||
|
||||
/** @ingroup mmio
|
||||
*@{
|
||||
*/
|
||||
|
||||
/** @brief Explicit read memory barrier
|
||||
/** \brief Explicit read memory barrier
|
||||
* Prevents reordering of reads around it.
|
||||
*/
|
||||
#define rbarr() do{}while(0)
|
||||
/** @brief Explicit write memory barrier
|
||||
/** \brief Explicit write memory barrier
|
||||
* Prevents reordering of writes around it.
|
||||
*/
|
||||
#define wbarr() do{}while(0)
|
||||
/** @brief Explicit read/write memory barrier
|
||||
/** \brief Explicit read/write memory barrier
|
||||
* Prevents reordering of reads or writes around it.
|
||||
*/
|
||||
#define rwbarr() do{}while(0)
|
||||
@@ -233,30 +239,30 @@ bswap32(epicsUInt32 value)
|
||||
*
|
||||
*@b PCI
|
||||
*
|
||||
@code
|
||||
\code
|
||||
be_iowrite16(base+off, 14);
|
||||
var = be_ioread16(base+off);
|
||||
@endcode
|
||||
\endcode
|
||||
*
|
||||
*@b VME
|
||||
*
|
||||
@code
|
||||
\code
|
||||
nat_iowrite16(base+off, 14);
|
||||
var = nat_ioread16(base+off);
|
||||
@endcode
|
||||
\endcode
|
||||
*
|
||||
*@subsection mmioexle Little endian device
|
||||
*
|
||||
*@b PCI
|
||||
@code
|
||||
\code
|
||||
le_iowrite16(base+off, 14);
|
||||
var = le_ioread16(base+off);
|
||||
@endcode
|
||||
\endcode
|
||||
*@b VME
|
||||
@code
|
||||
\code
|
||||
nat_iowrite16(base+off, bswap16(14));
|
||||
var = bswap16(nat_iowrite16(base+off));
|
||||
@endcode
|
||||
\endcode
|
||||
*This difference arises because VME bridges implement hardware byte
|
||||
*swapping on little endian systems, while PCI bridges do not.
|
||||
*Software accessing PCI devices must know if byte swapping is required.
|
||||
@@ -268,7 +274,9 @@ bswap32(epicsUInt32 value)
|
||||
*
|
||||
*Software accessing VME must @b not do conditional swapping.
|
||||
*
|
||||
*@note All read and write operations have an implicit read or write barrier.
|
||||
*\note All read and write operations have an implicit read or write barrier.
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* EPICSMMIODEF_H */
|
||||
|
||||
@@ -7,16 +7,15 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/**\file osiPoolStatus.h
|
||||
* \author Jeff Hill
|
||||
* \brief Functions to check the state of the system memory pool.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef INC_osiPoolStatus_H
|
||||
#define INC_osiPoolStatus_H
|
||||
|
||||
/*
|
||||
* Author: Jeff Hill
|
||||
*
|
||||
* Functions which interrogate the state of the system wide pool
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "shareLib.h"
|
||||
|
||||
@@ -24,12 +23,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tests to see if there is sufficent space for a block of the requested size
|
||||
* along with whatever additional free space is necessary to keep the system running
|
||||
* reliably
|
||||
/**\brief Checks if a memory block of a specific size can be safely allocated.
|
||||
*
|
||||
* this routine is called quite frequently so an efficent implementation is important
|
||||
* The meaning of "safely allocated" is target-specific, some additional free
|
||||
* space is usually necessary to keep the system running reliably.
|
||||
* On vxWorks this returns True if at least 100000 bytes is free.
|
||||
*
|
||||
* \note This routine is called quite frequently by the IOC so an efficent
|
||||
* implementation is important.
|
||||
*
|
||||
* \param contiguousBlockSize Block size to check.
|
||||
* \return True if the requested memory should be available.
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize );
|
||||
|
||||
|
||||
@@ -7,11 +7,21 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer Date: 15JUL99
|
||||
* Eric Norum
|
||||
* Ralph Lange <Ralph.Lange@gmx.de>
|
||||
/**
|
||||
* \file epicsRingBytes.h
|
||||
* \author Marty Kraimer, Eric Norum, Ralph Lange
|
||||
* \brief A circular buffer to store bytes
|
||||
*
|
||||
* \details
|
||||
* EpicsRingBytes provides a C API for creating and using ring buffers
|
||||
* (first in first out circular buffers) that store bytes. The unlocked
|
||||
* variant is designed so that one writer thread and one reader thread
|
||||
* can access the ring simultaneously without requiring mutual exclusion.
|
||||
* The locked variant uses an epicsSpinLock, and works with any numbers of
|
||||
* writer and reader threads.
|
||||
* \note If there is only one writer it is not necessary to lock for puts.
|
||||
* If there is a single reader it is not necessary to lock for gets.
|
||||
* epicsRingBytesLocked uses a spinlock.
|
||||
*/
|
||||
|
||||
#ifndef INCepicsRingBytesh
|
||||
@@ -23,35 +33,103 @@ extern "C" {
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/** \brief An identifier for a ring buffer */
|
||||
typedef void *epicsRingBytesId;
|
||||
typedef void const *epicsRingBytesIdConst;
|
||||
|
||||
/**
|
||||
* \brief Create a new ring buffer
|
||||
* \param nbytes Size of ring buffer to create
|
||||
* \return Ring buffer Id or NULL on failure
|
||||
*/
|
||||
epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int nbytes);
|
||||
/* Same, but secured by a spinlock */
|
||||
/**
|
||||
* \brief Create a new ring buffer, secured by a spinlock
|
||||
* \param nbytes Size of ring buffer to create
|
||||
* \return Ring buffer Id or NULL on failure
|
||||
*/
|
||||
epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesLockedCreate(int nbytes);
|
||||
/**
|
||||
* \brief Delete the ring buffer and free any associated memory
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Read data out of the ring buffer
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \param value Where to put the data fetched from the buffer
|
||||
* \param nbytes Maximum number of bytes to get
|
||||
* \return The number of bytes actually fetched
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesGet(
|
||||
epicsRingBytesId id, char *value,int nbytes);
|
||||
/**
|
||||
* \brief Write data into the ring buffer
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \param value Source of the data to be put into the buffer
|
||||
* \param nbytes How many bytes to put
|
||||
* \return The number of bytes actually stored, zero if not enough space
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
epicsRingBytesId id, char *value,int nbytes);
|
||||
/**
|
||||
* \brief Make the ring buffer empty
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \note Should only be used when both gets and puts are locked out.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Return the number of free bytes in the ring buffer
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return The number of free bytes in the ring buffer
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Return the number of bytes currently stored in the ring buffer
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return The number of bytes currently stored in the ring buffer
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Return the size of the ring buffer
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return Return the size of the ring buffer, i.e., nbytes specified in
|
||||
* the call to epicsRingBytesCreate().
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Test if the ring buffer is currently empty.
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return 1 if the buffer is empty, otherwise 0
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief Test if the ring buffer is currently full.
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return 1 if the buffer is full, otherwise 0
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id);
|
||||
/**
|
||||
* \brief See how full a ring buffer has been since it was last checked.
|
||||
*
|
||||
* Returns the maximum amount of data the ring buffer has held in bytes
|
||||
* since the water mark was last reset. A new ring buffer starts with a
|
||||
* water mark of 0.
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
* \return Actual Highwater mark
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesHighWaterMark(epicsRingBytesIdConst id);
|
||||
/**
|
||||
* \brief Reset the Highwater mark of the ring buffer.
|
||||
*
|
||||
* The Highwater mark will be set to the current usage
|
||||
* \param id RingbufferID returned by epicsRingBytesCreate()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesResetHighWaterMark(epicsRingBytesId id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* NOTES
|
||||
If there is only one writer it is not necessary to lock for put
|
||||
If there is a single reader it is not necessary to lock for puts
|
||||
|
||||
epicsRingBytesLocked uses a spinlock.
|
||||
*/
|
||||
|
||||
#endif /* INCepicsRingBytesh */
|
||||
|
||||
@@ -7,40 +7,92 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer Date: 15JUL99
|
||||
* Ralph Lange <Ralph.Lange@gmx.de>
|
||||
/**
|
||||
* \file epicsRingPointer.h
|
||||
* \brief A circular buffer to store pointers
|
||||
* \author Marty Kraimer, Ralph Lange
|
||||
*
|
||||
* \details
|
||||
* epicsRingPointer.h provides both C and C++ APIs for creating and using ring
|
||||
* buffers (first in first out circular buffers) that store pointers. The
|
||||
* unlocked kind is designed so that one writer thread and one reader thread
|
||||
* can access the ring simultaneously without requiring mutual exclusion. The
|
||||
* locked variant uses an epicsSpinLock, and works with any numbers of writer
|
||||
* and reader threads.
|
||||
* \note If there is only one writer it is not necessary to lock pushes.
|
||||
* If there is a single reader it is not necessary to lock pops.
|
||||
* epicsRingPointerLocked uses a spinlock.
|
||||
*/
|
||||
|
||||
#ifndef INCepicsRingPointerh
|
||||
#define INCepicsRingPointerh
|
||||
|
||||
/* NOTES
|
||||
* If there is only one writer it is not necessary to lock push
|
||||
* If there is a single reader it is not necessary to lock pop
|
||||
*
|
||||
* epicsRingPointerLocked uses a spinlock.
|
||||
*/
|
||||
|
||||
#include "epicsSpin.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* \brief A C++ template class providing methods for creating and using a ring
|
||||
* buffer (a first in, first out circular buffer) that stores pointers to
|
||||
* objects of the template type.
|
||||
*/
|
||||
template <class T>
|
||||
class epicsRingPointer {
|
||||
public: /* Functions */
|
||||
/**\brief Constructor
|
||||
* \param size Maximum number of elements (pointers) that can be stored
|
||||
* \param locked If true, the spin lock secured variant is created
|
||||
*/
|
||||
epicsRingPointer(int size, bool locked);
|
||||
/**\brief Destructor
|
||||
*/
|
||||
~epicsRingPointer();
|
||||
/**\brief Push a new entry on the ring
|
||||
* \return True on success, False if the buffer was full
|
||||
*/
|
||||
bool push(T *p);
|
||||
/**\brief Take an element off the ring
|
||||
* \return The element, or NULL if the ring was empty
|
||||
*/
|
||||
T* pop();
|
||||
/**\brief Remove all elements from the ring.
|
||||
* \note If this operation is performed on a ring buffer of the
|
||||
* unsecured kind, all access to the ring should be locked.
|
||||
*/
|
||||
void flush();
|
||||
/**\brief Get how much free space remains in the ring
|
||||
* \return The number of additional elements the ring could hold.
|
||||
*/
|
||||
int getFree() const;
|
||||
/**\brief Get how many elements are stored on the ring
|
||||
* \return The number of elements currently stored.
|
||||
*/
|
||||
int getUsed() const;
|
||||
/**\brief Get the size of the ring
|
||||
* \return The \c size specified when the ring was created.
|
||||
*/
|
||||
int getSize() const;
|
||||
/**\brief Test if the ring is currently empty
|
||||
* \return True if the ring is empty, otherwise false.
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
/**\brief Test if the ring is currently full
|
||||
* \return True if the ring is full, otherwise false.
|
||||
*/
|
||||
bool isFull() const;
|
||||
/**\brief See how full the ring has got since it was last checked.
|
||||
*
|
||||
* Returns the maximum number of elements the ring
|
||||
* buffer has held since the water mark was last reset.
|
||||
* A new ring buffer starts with a water mark of 0.
|
||||
* \return Actual highwater mark
|
||||
*/
|
||||
int getHighWaterMark() const;
|
||||
/**\brief Reset high water mark
|
||||
*
|
||||
* High water mark will be set to the current usage
|
||||
*/
|
||||
void resetHighWaterMark();
|
||||
|
||||
private: /* Prevent compiler-generated member functions */
|
||||
@@ -62,24 +114,93 @@ private: /* Data */
|
||||
extern "C" {
|
||||
#endif /*__cplusplus */
|
||||
|
||||
/** \brief An identifier for the C API to a ring buffer storing pointers */
|
||||
typedef void *epicsRingPointerId;
|
||||
typedef void const *epicsRingPointerIdConst;
|
||||
|
||||
/**
|
||||
* \brief Create a new ring buffer
|
||||
* \param size Size of ring buffer to create
|
||||
* \return Ring buffer identifier or NULL on failure
|
||||
*/
|
||||
epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size);
|
||||
/* Same, but secured by a spinlock */
|
||||
/**
|
||||
* \brief Create a new ring buffer, secured by a spinlock
|
||||
* \param size Size of ring buffer to create
|
||||
* \return Ring buffer identifier or NULL on failure
|
||||
*/
|
||||
epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerLockedCreate(int size);
|
||||
/**
|
||||
* \brief Delete the ring buffer and free any associated memory
|
||||
* \param id Ring buffer identifier
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id);
|
||||
/*ringPointerPush returns (0,1) if p (was not, was) put on ring*/
|
||||
/**
|
||||
* \brief Push pointer into the ring buffer
|
||||
* \param id Ring buffer identifier
|
||||
* \param p Pointer to be pushed to the ring
|
||||
* \return 1 if the pointer was successfully pushed, 0 if the buffer was full
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id,void *p);
|
||||
/*ringPointerPop returns 0 if ring is empty*/
|
||||
/**
|
||||
* \brief Take an element off the ring
|
||||
* \param id Ring buffer identifier
|
||||
* \return The pointer from the buffer, or NULL if the ring was empty
|
||||
*/
|
||||
epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) ;
|
||||
/**
|
||||
* \brief Remove all elements from the ring
|
||||
* \param id Ring buffer identifier
|
||||
* \note If this operation is performed on a ring buffer of the unsecured
|
||||
* kind, all access to the ring should be locked.
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Return the amount of empty space in the ring buffer
|
||||
* \param id Ring buffer identifier
|
||||
* \return The number of additional elements it could hold.
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Return the number of elements stored in the ring buffer
|
||||
* \param id Ring buffer identifier
|
||||
* \return The number of elements stored in the ring buffer
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Return the size of the ring
|
||||
* \param id Ring buffer identifier
|
||||
* \return The size of the ring buffer, i.e. the value of \c size
|
||||
* given when the ring was created.
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Check if the ring buffer is currently empty
|
||||
* \param id Ring buffer identifier
|
||||
* \return 1 if the ring is empty, otherwise 0
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Check if the ring buffer is currently full
|
||||
* \param id Ring buffer identifier
|
||||
* \return 1 if the ring buffer is full, otherwise 0
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id);
|
||||
/**
|
||||
* \brief Get the Highwater mark of the ring buffer
|
||||
*
|
||||
* Returns the largest number of elements the ring buffer has held since
|
||||
* the water mark was last reset. A new ring buffer starts with a
|
||||
* water mark of 0.
|
||||
* \param id Ring buffer identifier
|
||||
* \return Actual Highwater mark
|
||||
*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetHighWaterMark(epicsRingPointerIdConst id);
|
||||
/**
|
||||
* \brief Reset the Highwater mark of the ring buffer
|
||||
*
|
||||
* The Highwater mark will be set to the current usage
|
||||
* \param id Ring buffer identifier
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerResetHighWaterMark(epicsRingPointerId id);
|
||||
|
||||
/* This routine was incorrectly named in previous releases */
|
||||
@@ -92,12 +213,6 @@ epicsShareFunc void epicsShareAPI epicsRingPointerResetHighWaterMark(epicsRingPo
|
||||
|
||||
/* INLINE FUNCTIONS */
|
||||
|
||||
/* Algorithm note
|
||||
* Space is allocated for one additional element.
|
||||
* A put request is rejected if the it would cause nextPush to equal nextPop
|
||||
* The algorithm does not require locking puts for a single writer
|
||||
* or locking of gets for a single reader
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
/**
|
||||
* \file yajl_alloc.h
|
||||
* default memory allocation routines for yajl which use malloc/realloc and
|
||||
* free
|
||||
* \brief Memory allocation macros for yajl
|
||||
* \author Lloyd Hilaiel
|
||||
*
|
||||
* These macros are used inside YAJL instead of directly calling
|
||||
* malloc(), realloc() or free(). They call the equivalent method
|
||||
* in their \ref yajl_alloc_funcs parameter \a afs.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_ALLOC_H__
|
||||
|
||||
@@ -26,47 +26,54 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file yajl_common.h
|
||||
* \brief Common routines and macros used by other YAJL APIs.
|
||||
* \author Lloyd Hilaiel
|
||||
*/
|
||||
|
||||
/** YAJL API history in brief
|
||||
*
|
||||
* Originally macro not defined
|
||||
* YAJL 1.0.12
|
||||
* Bundled with EPICS Base 3.15.0.1
|
||||
* This macro was not defined in the
|
||||
* YAJL 1.0.12 version that was
|
||||
* bundled with EPICS Base 3.15.0.1
|
||||
*
|
||||
* YAJL 2.1.0
|
||||
* Changes argument type for yajl_integer() from 'int' to 'long long'
|
||||
* Changes argument type for yajl_string() and yajl_map_key() from 'unsigned' to 'size_t'
|
||||
* Replacement of struct yajl_parser_config with yajl_config()
|
||||
* Replacement of yajl_parse_complete() with yajl_complete_parse()
|
||||
* \li Changes argument type for yajl_integer() from \c int to \c long \c long
|
||||
* \li Changes argument type for yajl_string() and yajl_map_key() from \c unsigned to \c size_t
|
||||
* \li Replacement of struct yajl_parser_config with yajl_config()
|
||||
* \li Replacement of yajl_parse_complete() with yajl_complete_parse()
|
||||
*/
|
||||
#define EPICS_YAJL_VERSION VERSION_INT(2,1,0,0)
|
||||
|
||||
/** Maximum generation depth for YAJL's JSON generation routines */
|
||||
#define YAJL_MAX_DEPTH 128
|
||||
|
||||
/** Symbol decoration for Microsoft builds */
|
||||
#define YAJL_API LIBCOM_API
|
||||
|
||||
/** pointer to a malloc function, supporting client overriding memory
|
||||
/** Pointer to a malloc() function, supporting client overriding memory
|
||||
* allocation routines */
|
||||
typedef void * (*yajl_malloc_func)(void *ctx, size_t sz);
|
||||
|
||||
/** pointer to a free function, supporting client overriding memory
|
||||
/** Pointer to a free() function, supporting client overriding memory
|
||||
* allocation routines */
|
||||
typedef void (*yajl_free_func)(void *ctx, void * ptr);
|
||||
|
||||
/** pointer to a realloc function which can resize an allocation. */
|
||||
/** Pointer to a realloc() function which can resize an allocation. */
|
||||
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, size_t sz);
|
||||
|
||||
/** A structure which can be passed to yajl_*_alloc routines to allow the
|
||||
* client to specify memory allocation functions to be used. */
|
||||
typedef struct
|
||||
{
|
||||
/** pointer to a function that can allocate uninitialized memory */
|
||||
/** Pointer to a function that can allocate uninitialized memory */
|
||||
yajl_malloc_func malloc;
|
||||
/** pointer to a function that can resize memory allocations */
|
||||
/** Pointer to a function that can resize memory allocations */
|
||||
yajl_realloc_func realloc;
|
||||
/** pointer to a function that can free memory allocated using
|
||||
/** Pointer to a function that can free memory allocated using
|
||||
* reallocFunction or mallocFunction */
|
||||
yajl_free_func free;
|
||||
/** a context pointer that will be passed to above allocation routines */
|
||||
/** A context pointer that will be passed to above allocation routines */
|
||||
void * ctx;
|
||||
} yajl_alloc_funcs;
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
/**
|
||||
* \file yajl_gen.h
|
||||
* Interface to YAJL's JSON generation facilities.
|
||||
* \brief Interface to YAJL's JSON generation facilities.
|
||||
* \author Lloyd Hilaiel
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_GEN_H__
|
||||
@@ -27,49 +28,49 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/** generator status codes */
|
||||
/** Generator status codes */
|
||||
typedef enum {
|
||||
/** no error */
|
||||
/** No error */
|
||||
yajl_gen_status_ok = 0,
|
||||
/** at a point where a map key is generated, a function other than
|
||||
* yajl_gen_string was called */
|
||||
/** At a point where a map key is generated, a function other than
|
||||
* yajl_gen_string() was called */
|
||||
yajl_gen_keys_must_be_strings,
|
||||
/** YAJL's maximum generation depth was exceeded. see
|
||||
* YAJL_MAX_DEPTH */
|
||||
* \ref YAJL_MAX_DEPTH */
|
||||
yajl_max_depth_exceeded,
|
||||
/** A generator function (yajl_gen_XXX) was called while in an error
|
||||
* state */
|
||||
yajl_gen_in_error_state,
|
||||
/** A complete JSON document has been generated */
|
||||
yajl_gen_generation_complete,
|
||||
/** yajl_gen_double was passed an invalid floating point value
|
||||
/** yajl_gen_double() was passed an invalid floating point value
|
||||
* (infinity or NaN). */
|
||||
yajl_gen_invalid_number,
|
||||
/** A print callback was passed in, so there is no internal
|
||||
* buffer to get from */
|
||||
yajl_gen_no_buf,
|
||||
/** returned from yajl_gen_string() when the yajl_gen_validate_utf8
|
||||
/** Returned from yajl_gen_string() when the yajl_gen_validate_utf8()
|
||||
* option is enabled and an invalid was passed by client code.
|
||||
*/
|
||||
yajl_gen_invalid_string
|
||||
} yajl_gen_status;
|
||||
|
||||
/** an opaque handle to a generator */
|
||||
/** An opaque handle to a generator */
|
||||
typedef struct yajl_gen_t * yajl_gen;
|
||||
|
||||
/** a callback used for "printing" the results. */
|
||||
/** A callback used for "printing" the results. */
|
||||
typedef void (*yajl_print_t)(void * ctx,
|
||||
const char * str,
|
||||
size_t len);
|
||||
|
||||
/** configuration parameters for the parser, these may be passed to
|
||||
/** Configuration parameters for the parser, these may be passed to
|
||||
* yajl_gen_config() along with option specific argument(s). In general,
|
||||
* all configuration parameters default to *off*. */
|
||||
typedef enum {
|
||||
/** generate indented (beautiful) output */
|
||||
/** Generate indented (beautiful) output */
|
||||
yajl_gen_beautify = 0x01,
|
||||
/**
|
||||
* Set an indent string which is used when yajl_gen_beautify
|
||||
* Set an indent string which is used when yajl_gen_beautify()
|
||||
* is enabled. Maybe something like \\t or some number of
|
||||
* spaces. The default is four spaces ' '.
|
||||
*/
|
||||
@@ -77,11 +78,12 @@ extern "C" {
|
||||
/**
|
||||
* Set a function and context argument that should be used to
|
||||
* output generated json. the function should conform to the
|
||||
* yajl_print_t prototype while the context argument is a
|
||||
* yajl_print_t() prototype while the context argument is a
|
||||
* void * of your choosing.
|
||||
*
|
||||
* example:
|
||||
* Example: \code{.cpp}
|
||||
* yajl_gen_config(g, yajl_gen_print_callback, myFunc, myVoidPtr);
|
||||
* \endcode
|
||||
*/
|
||||
yajl_gen_print_callback = 0x04,
|
||||
/**
|
||||
@@ -91,7 +93,7 @@ extern "C" {
|
||||
*/
|
||||
yajl_gen_validate_utf8 = 0x08,
|
||||
/**
|
||||
* the forward solidus (slash or '/' in human) is not required to be
|
||||
* The forward solidus (slash or '/' in human) is not required to be
|
||||
* escaped in json text. By default, YAJL will not escape it in the
|
||||
* iterest of saving bytes. Setting this flag will cause YAJL to
|
||||
* always escape '/' in generated JSON strings.
|
||||
@@ -99,51 +101,62 @@ extern "C" {
|
||||
yajl_gen_escape_solidus = 0x10
|
||||
} yajl_gen_option;
|
||||
|
||||
/** allow the modification of generator options subsequent to handle
|
||||
* allocation (via yajl_alloc)
|
||||
/** Allow the modification of generator options subsequent to handle
|
||||
* allocation (via yajl_alloc())
|
||||
* \returns zero in case of errors, non-zero otherwise
|
||||
*/
|
||||
YAJL_API int yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...);
|
||||
|
||||
/** allocate a generator handle
|
||||
* \param allocFuncs an optional pointer to a structure which allows
|
||||
/** Allocate a generator handle
|
||||
* \param allocFuncs An optional pointer to a structure which allows
|
||||
* the client to overide the memory allocation
|
||||
* used by yajl. May be NULL, in which case
|
||||
* malloc/free/realloc will be used.
|
||||
* malloc(), free() and realloc() will be used.
|
||||
*
|
||||
* \returns an allocated handle on success, NULL on failure (bad params)
|
||||
*/
|
||||
YAJL_API yajl_gen yajl_gen_alloc(const yajl_alloc_funcs * allocFuncs);
|
||||
|
||||
/** free a generator handle */
|
||||
/** Free a generator handle */
|
||||
YAJL_API void yajl_gen_free(yajl_gen handle);
|
||||
|
||||
/** Generate an integer number. */
|
||||
YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number);
|
||||
/** generate a floating point number. number may not be infinity or
|
||||
/** Generate a floating point number. \p number may not be infinity or
|
||||
* NaN, as these have no representation in JSON. In these cases the
|
||||
* generator will return 'yajl_gen_invalid_number' */
|
||||
* generator will return \ref yajl_gen_invalid_number */
|
||||
YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number);
|
||||
/** Generate a number from the string given in \p num. */
|
||||
YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand,
|
||||
const char * num,
|
||||
size_t len);
|
||||
/** Generate a string value or map key from \p str. */
|
||||
YAJL_API yajl_gen_status yajl_gen_string(yajl_gen hand,
|
||||
const unsigned char * str,
|
||||
size_t len);
|
||||
/** Generate a \c null value. */
|
||||
YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand);
|
||||
/** Generate a \c true or \c false value from \p boolean. */
|
||||
YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean);
|
||||
/** Start generating a JSON map. This should be followed by calls to
|
||||
* yajl_gen_string() to provide a key and another yajl_gen routine
|
||||
* to provide the value associated with that key. */
|
||||
YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand);
|
||||
/** Finish generating a JSON map. */
|
||||
YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand);
|
||||
/** Start generating a JSON array. */
|
||||
YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand);
|
||||
/** Finish generating a JSON array. */
|
||||
YAJL_API yajl_gen_status yajl_gen_array_close(yajl_gen hand);
|
||||
|
||||
/** access the null terminated generator buffer. If incrementally
|
||||
* outputing JSON, one should call yajl_gen_clear to clear the
|
||||
/** Access the null terminated generator buffer. If incrementally
|
||||
* outputing JSON, one should call yajl_gen_clear() to clear the
|
||||
* buffer. This allows stream generation. */
|
||||
YAJL_API yajl_gen_status yajl_gen_get_buf(yajl_gen hand,
|
||||
const unsigned char ** buf,
|
||||
size_t * len);
|
||||
|
||||
/** clear yajl's output buffer, but maintain all internal generation
|
||||
/** Clear yajl's output buffer, but maintain all internal generation
|
||||
* state. This function will not "reset" the generator state, and is
|
||||
* intended to enable incremental JSON outputing. */
|
||||
YAJL_API void yajl_gen_clear(yajl_gen hand);
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
/**
|
||||
* \file yajl_parse.h
|
||||
* Interface to YAJL's JSON stream parsing facilities.
|
||||
* \brief Interface to YAJL's JSON stream parsing facilities.
|
||||
* \author Lloyd Hilaiel
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_PARSE_H__
|
||||
@@ -27,47 +28,45 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/** error codes returned from this interface */
|
||||
/** Error codes returned from this interface */
|
||||
typedef enum {
|
||||
/** no error was encountered */
|
||||
/** No error was encountered */
|
||||
yajl_status_ok,
|
||||
/** a client callback returned zero, stopping the parse */
|
||||
/** A client callback returned zero, stopping the parse */
|
||||
yajl_status_client_canceled,
|
||||
/** An error occured during the parse. Call yajl_get_error for
|
||||
/** An error occured during the parse. Call yajl_get_error() for
|
||||
* more information about the encountered error */
|
||||
yajl_status_error
|
||||
} yajl_status;
|
||||
|
||||
/** attain a human readable, english, string for an error */
|
||||
/** Attain a human readable, english, string for an error */
|
||||
YAJL_API const char * yajl_status_to_string(yajl_status code);
|
||||
|
||||
/** an opaque handle to a parser */
|
||||
/** An opaque handle to a parser */
|
||||
typedef struct yajl_handle_t * yajl_handle;
|
||||
|
||||
/** yajl is an event driven parser. this means as json elements are
|
||||
/** YAJL is an event driven parser. This means as json elements are
|
||||
* parsed, you are called back to do something with the data. The
|
||||
* functions in this table indicate the various events for which
|
||||
* you will be called back. Each callback accepts a "context"
|
||||
* pointer, this is a void * that is passed into the yajl_parse
|
||||
* pointer, this is a void * that is passed into the yajl_parse()
|
||||
* function which the client code may use to pass around context.
|
||||
*
|
||||
* All callbacks return an integer. If non-zero, the parse will
|
||||
* continue. If zero, the parse will be canceled and
|
||||
* yajl_status_client_canceled will be returned from the parse.
|
||||
* yajl_status_client_canceled() will be returned from the parse.
|
||||
*
|
||||
* \attention {
|
||||
* \attention
|
||||
* A note about the handling of numbers:
|
||||
*
|
||||
* yajl will only convert numbers that can be represented in a
|
||||
* double or a 64 bit (long long) int. All other numbers will
|
||||
* be passed to the client in string form using the yajl_number
|
||||
* callback. Furthermore, if yajl_number is not NULL, it will
|
||||
* always be used to return numbers, that is yajl_integer and
|
||||
* yajl_double will be ignored. If yajl_number is NULL but one
|
||||
* of yajl_integer or yajl_double are defined, parsing of a
|
||||
* be passed to the client in string form using the yajl_number()
|
||||
* callback. Furthermore, if yajl_number() is not NULL, it will
|
||||
* always be used to return numbers, that is yajl_integer() and
|
||||
* yajl_double() will be ignored. If yajl_number() is NULL but one
|
||||
* of yajl_integer() or yajl_double() are defined, parsing of a
|
||||
* number larger than is representable in a double or 64 bit
|
||||
* integer will result in a parse error.
|
||||
* }
|
||||
*/
|
||||
typedef struct {
|
||||
int (* yajl_null)(void * ctx);
|
||||
@@ -79,7 +78,7 @@ extern "C" {
|
||||
int (* yajl_number)(void * ctx, const char * numberVal,
|
||||
size_t numberLen);
|
||||
|
||||
/** strings are returned as pointers into the JSON text when,
|
||||
/** Strings are returned as pointers into the JSON text when,
|
||||
* possible, as a result, they are _not_ null padded */
|
||||
int (* yajl_string)(void * ctx, const unsigned char * stringVal,
|
||||
size_t stringLen);
|
||||
@@ -93,8 +92,8 @@ extern "C" {
|
||||
int (* yajl_end_array)(void * ctx);
|
||||
} yajl_callbacks;
|
||||
|
||||
/** allocate a parser handle
|
||||
* \param callbacks a yajl callbacks structure specifying the
|
||||
/** Allocate a parser handle
|
||||
* \param callbacks A yajl callbacks structure specifying the
|
||||
* functions to call when different JSON entities
|
||||
* are encountered in the input text. May be NULL,
|
||||
* which is only useful for validation.
|
||||
@@ -107,7 +106,7 @@ extern "C" {
|
||||
void * ctx);
|
||||
|
||||
|
||||
/** configuration parameters for the parser, these may be passed to
|
||||
/** Configuration parameters for the parser, these may be passed to
|
||||
* yajl_config() along with option specific argument(s). In general,
|
||||
* all configuration parameters default to *off*. */
|
||||
typedef enum {
|
||||
@@ -115,8 +114,9 @@ extern "C" {
|
||||
* JSON input. Non-standard, but rather fun
|
||||
* arguments: toggled off with integer zero, on otherwise.
|
||||
*
|
||||
* example:
|
||||
* Example: \code{.cpp}
|
||||
* yajl_config(h, yajl_allow_comments, 1); // turn comment support on
|
||||
* \endcode
|
||||
*/
|
||||
yajl_allow_comments = 0x01,
|
||||
/**
|
||||
@@ -125,8 +125,9 @@ extern "C" {
|
||||
* this option makes parsing slightly more expensive (~7% depending
|
||||
* on processor and compiler in use)
|
||||
*
|
||||
* example:
|
||||
* Example: \code{.cpp}
|
||||
* yajl_config(h, yajl_dont_validate_strings, 1); // disable utf8 checking
|
||||
* \endcode
|
||||
*/
|
||||
yajl_dont_validate_strings = 0x02,
|
||||
/**
|
||||
@@ -157,17 +158,17 @@ extern "C" {
|
||||
yajl_allow_partial_values = 0x10
|
||||
} yajl_option;
|
||||
|
||||
/** allow the modification of parser options subsequent to handle
|
||||
* allocation (via yajl_alloc)
|
||||
/** Allow the modification of parser options subsequent to handle
|
||||
* allocation (via yajl_alloc())
|
||||
* \returns zero in case of errors, non-zero otherwise
|
||||
*/
|
||||
YAJL_API int yajl_config(yajl_handle h, yajl_option opt, ...);
|
||||
|
||||
/** free a parser handle */
|
||||
/** Free a parser handle */
|
||||
YAJL_API void yajl_free(yajl_handle handle);
|
||||
|
||||
/** Parse some json!
|
||||
* \param hand - a handle to the json parser allocated with yajl_alloc
|
||||
* \param hand - a handle to the json parser allocated with yajl_alloc()
|
||||
* \param jsonText - a pointer to the UTF8 json text to be parsed
|
||||
* \param jsonTextLength - the length, in bytes, of input text
|
||||
*/
|
||||
@@ -182,11 +183,11 @@ extern "C" {
|
||||
* yajl can't know whether another digit is next or some character
|
||||
* that would terminate the integer token.
|
||||
*
|
||||
* \param hand - a handle to the json parser allocated with yajl_alloc
|
||||
* \param hand - a handle to the json parser allocated with yajl_alloc()
|
||||
*/
|
||||
YAJL_API yajl_status yajl_complete_parse(yajl_handle hand);
|
||||
|
||||
/** get an error string describing the state of the
|
||||
/** Get an error string describing the state of the
|
||||
* parse.
|
||||
*
|
||||
* If verbose is non-zero, the message will include the JSON
|
||||
@@ -194,14 +195,14 @@ extern "C" {
|
||||
* the specific char.
|
||||
*
|
||||
* \returns A dynamically allocated string will be returned which should
|
||||
* be freed with yajl_free_error
|
||||
* be freed with yajl_free_error()
|
||||
*/
|
||||
YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose,
|
||||
const unsigned char * jsonText,
|
||||
size_t jsonTextLength);
|
||||
|
||||
/**
|
||||
* get the amount of data consumed from the last chunk passed to YAJL.
|
||||
* Get the amount of data consumed from the last chunk passed to YAJL.
|
||||
*
|
||||
* In the case of a successful parse this can help you understand if
|
||||
* the entire buffer was consumed (which will allow you to handle
|
||||
@@ -214,7 +215,7 @@ extern "C" {
|
||||
*/
|
||||
YAJL_API size_t yajl_get_bytes_consumed(yajl_handle hand);
|
||||
|
||||
/** free an error returned from yajl_get_error */
|
||||
/** Free an error returned from yajl_get_error() */
|
||||
YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user