Merged changes from 3.15 branch, to revno 12807

This commit is contained in:
Andrew Johnson
2017-02-01 11:57:04 -06:00
90 changed files with 1401 additions and 959 deletions

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2002 The University of Saskatchewan
* 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.
\*************************************************************************/
/*
* RTEMS startup task for EPICS
@@ -287,27 +287,27 @@ initialize_remote_filesystem(char **argv, int hasLocalFilesystem)
mount_point[l] = '\0';
argv[1] = rtems_bsdnet_bootp_cmdline;
/*
* Its probably common to embed the mount point in the server
* Its probably common to embed the mount point in the server
* name so, when this is occurring, dont clobber the mount point
* by appending the first node from the command path. This allows
* the mount point to be a different path then the server's mount
* the mount point to be a different path then the server's mount
* path.
*
* This allows for example a line similar to as follows the DHCP
* This allows for example a line similar to as follows the DHCP
* configuration file.
*
* server-name "159.233@192.168.0.123:/vol/vol0/bootRTEMS";
*/
if ( server_name ) {
const size_t allocSize = strlen ( server_name ) + 2;
char * const pServerName = mustMalloc( allocSize,
char * const pServerName = mustMalloc( allocSize,
"NFS mount paths");
char * const pServerPath = mustMalloc ( allocSize,
char * const pServerPath = mustMalloc ( allocSize,
"NFS mount paths");
const int scanfStatus = sscanf (
server_name,
"%[^:] : / %s",
pServerName,
const int scanfStatus = sscanf (
server_name,
"%[^:] : / %s",
pServerName,
pServerPath + 1u );
if ( scanfStatus == 2 ) {
pServerPath[0u]= '/';
@@ -535,7 +535,7 @@ exitHandler(void)
rtems_task
Init (rtems_task_argument ignored)
{
int i;
int result;
char *argv[3] = { NULL, NULL, NULL };
char *cp;
rtems_task_priority newpri;
@@ -661,8 +661,8 @@ Init (rtems_task_argument ignored)
atexit(exitHandler);
errlogFlush();
printf ("***** Starting EPICS application *****\n");
i = main ((sizeof argv / sizeof argv[0]) - 1, argv);
result = main ((sizeof argv / sizeof argv[0]) - 1, argv);
printf ("***** IOC application terminating *****\n");
epicsThreadSleep(1.0);
epicsExit(0);
epicsExit(result);
}

View File

@@ -68,7 +68,7 @@ INP{link} {
\n { line_num ++;}
. {
char message[20];
char message[40];
YY_BUFFER_STATE *dummy=0;
sprintf(message,"invalid character '%c'",yytext[0]);

View File

@@ -10,3 +10,4 @@
SRC_DIRS += $(LIBCOM)/ellLib
INC += ellLib.h
Com_SRCS += ellLib.c
Com_SRCS += ellSort.c

View File

@@ -56,6 +56,8 @@ epicsShareFunc void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode);
epicsShareFunc ELLNODE * ellNth (ELLLIST *pList, int nodeNum);
epicsShareFunc ELLNODE * ellNStep (ELLNODE *pNode, int nStep);
epicsShareFunc int ellFind (ELLLIST *pList, ELLNODE *pNode);
typedef int (*pListCmp)(const ELLNODE* A, const ELLNODE* B);
epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp);
epicsShareFunc void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc);
epicsShareFunc void ellVerify (ELLLIST *pList);

View File

@@ -0,0 +1,83 @@
/*************************************************************************\
* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Argonne
* National Laboratory.
* Copyright (c) 2016 Michael Davidsaver
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Use of mergesort algorithm based on analysis by
* http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
*/
#include <stdlib.h>
#define epicsExportSharedSymbols
#include "epicsAssert.h"
#include "ellLib.h"
static void ellMoveN(ELLLIST* pTo, ELLLIST* pFrom, int count )
{
for(;count && ellCount(pFrom); count--) {
ELLNODE *node = ellGet(pFrom);
ellAdd(pTo, node);
}
}
/* Stable (MergeSort) to given list.
* The comparison function cmp(A,B) is expected
* to return -1 for A<B, 0 for A==B, and 1 for A>B.
*/
void ellSortStable(ELLLIST *pList, pListCmp cmp)
{
ELLLIST INP, P, Q;
size_t insize = 1; /* initial sub-list size */
if(ellCount(pList)<=1)
return;
ellInit(&INP);
ellInit(&P);
ellInit(&Q);
/* Process is to iteratively sort
* a sequence of sub-lists of size 'insize'
*/
while(insize < ellCount(pList)) {
assert(ellCount(&INP)==0);
/* shift previous results to inputs */
ellConcat(&INP, pList);
while(ellCount(&INP))
{
ELLNODE *p, *q;
/* Pull out the next pair of sub-lists */
ellMoveN(&Q, &INP, insize);
ellMoveN(&P, &INP, insize);
/* merge these sub-lists */
while((p=ellFirst(&P)) && (q=ellFirst(&Q)))
{
if((*cmp)(p,q) < 0) {
ellAdd(pList, ellGet(&P));
} else {
ellAdd(pList, ellGet(&Q));
}
}
/* concatenate any remaining to result */
if(ellFirst(&P))
ellConcat(pList, &P);
else if(ellFirst(&Q))
ellConcat(pList, &Q);
assert(!ellFirst(&P) && !ellFirst(&Q));
}
insize *= 2;
}
}

View File

@@ -559,6 +559,7 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
if (macros) {
if (macParseDefns(NULL, macros, &defines) < 0) {
free(redirects);
return -1;
}
}
@@ -571,6 +572,7 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
if (handle == NULL) {
if (macCreateHandle(&handle, pairs)) {
errlogMessage("iocsh: macCreateHandle failed.");
free(redirects);
return -1;
}

View File

@@ -84,131 +84,132 @@ static int sighupPipe[2];
/*
*
* main()
* main()
*
*/
int main(void)
{
struct sockaddr_in serverAddr; /* server's address */
struct timeval timeout;
int status;
struct ioc_log_server *pserver;
struct sockaddr_in serverAddr; /* server's address */
struct timeval timeout;
int status;
struct ioc_log_server *pserver;
osiSockIoctl_t optval;
osiSockIoctl_t optval;
status = getConfig();
if(status<0){
fprintf(stderr, "iocLogServer: EPICS environment underspecified\n");
fprintf(stderr, "iocLogServer: failed to initialize\n");
return IOCLS_ERROR;
}
status = getConfig();
if (status<0) {
fprintf(stderr, "iocLogServer: EPICS environment underspecified\n");
fprintf(stderr, "iocLogServer: failed to initialize\n");
return IOCLS_ERROR;
}
pserver = (struct ioc_log_server *)
calloc(1, sizeof *pserver);
if(!pserver){
fprintf(stderr, "iocLogServer: %s\n", strerror(errno));
return IOCLS_ERROR;
}
pserver = (struct ioc_log_server *)
calloc(1, sizeof *pserver);
if (!pserver) {
fprintf(stderr, "iocLogServer: %s\n", strerror(errno));
return IOCLS_ERROR;
}
pserver->pfdctx = (void *) fdmgr_init();
if(!pserver->pfdctx){
fprintf(stderr, "iocLogServer: %s\n", strerror(errno));
return IOCLS_ERROR;
}
pserver->pfdctx = (void *) fdmgr_init();
if (!pserver->pfdctx) {
fprintf(stderr, "iocLogServer: %s\n", strerror(errno));
return IOCLS_ERROR;
}
/*
* Open the socket. Use ARPA Internet address format and stream
* sockets. Format described in <sys/socket.h>.
*/
pserver->sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0);
if (pserver->sock==INVALID_SOCKET) {
/*
* Open the socket. Use ARPA Internet address format and stream
* sockets. Format described in <sys/socket.h>.
*/
pserver->sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0);
if (pserver->sock == INVALID_SOCKET) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
fprintf(stderr, "iocLogServer: sock create err: %s\n", sockErrBuf);
return IOCLS_ERROR;
}
fprintf(stderr, "iocLogServer: sock create err: %s\n", sockErrBuf);
free(pserver);
return IOCLS_ERROR;
}
epicsSocketEnableAddressReuseDuringTimeWaitState ( pserver->sock );
/* Zero the sock_addr structure */
memset((void *)&serverAddr, 0, sizeof serverAddr);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(ioc_log_port);
/* Zero the sock_addr structure */
memset((void *)&serverAddr, 0, sizeof serverAddr);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(ioc_log_port);
/* get server's Internet address */
status = bind ( pserver->sock,
(struct sockaddr *)&serverAddr,
sizeof (serverAddr) );
if (status<0) {
/* get server's Internet address */
status = bind ( pserver->sock,
(struct sockaddr *)&serverAddr,
sizeof (serverAddr) );
if (status < 0) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
fprintf(stderr, "iocLogServer: bind err: %s\n", sockErrBuf );
fprintf (stderr,
"iocLogServer: a server is already installed on port %u?\n",
(unsigned)ioc_log_port);
return IOCLS_ERROR;
}
fprintf(stderr, "iocLogServer: bind err: %s\n", sockErrBuf );
fprintf (stderr,
"iocLogServer: a server is already installed on port %u?\n",
(unsigned)ioc_log_port);
return IOCLS_ERROR;
}
/* listen and accept new connections */
status = listen(pserver->sock, 10);
if (status<0) {
/* listen and accept new connections */
status = listen(pserver->sock, 10);
if (status < 0) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
fprintf(stderr, "iocLogServer: listen err %s\n", sockErrBuf);
return IOCLS_ERROR;
}
fprintf(stderr, "iocLogServer: listen err %s\n", sockErrBuf);
return IOCLS_ERROR;
}
/*
* Set non blocking IO
* to prevent dead locks
*/
optval = TRUE;
status = socket_ioctl(
pserver->sock,
FIONBIO,
&optval);
if(status<0){
/*
* Set non blocking IO
* to prevent dead locks
*/
optval = TRUE;
status = socket_ioctl(
pserver->sock,
FIONBIO,
&optval);
if (status < 0){
char sockErrBuf[64];
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
fprintf(stderr, "iocLogServer: ioctl FIONBIO err %s\n", sockErrBuf);
return IOCLS_ERROR;
}
fprintf(stderr, "iocLogServer: ioctl FIONBIO err %s\n", sockErrBuf);
return IOCLS_ERROR;
}
# ifdef UNIX
status = setupSIGHUP(pserver);
if (status<0) {
return IOCLS_ERROR;
}
# endif
# ifdef UNIX
status = setupSIGHUP(pserver);
if (status < 0) {
return IOCLS_ERROR;
}
# endif
status = openLogFile(pserver);
if (status<0) {
fprintf(stderr,
"File access problems to `%s' because `%s'\n",
ioc_log_file_name,
strerror(errno));
return IOCLS_ERROR;
}
status = openLogFile(pserver);
if (status < 0) {
fprintf(stderr,
"File access problems to `%s' because `%s'\n",
ioc_log_file_name,
strerror(errno));
return IOCLS_ERROR;
}
status = fdmgr_add_callback(
pserver->pfdctx,
pserver->sock,
fdi_read,
acceptNewClient,
pserver);
if(status<0){
fprintf(stderr,
"iocLogServer: failed to add read callback\n");
return IOCLS_ERROR;
}
status = fdmgr_add_callback(
pserver->pfdctx,
pserver->sock,
fdi_read,
acceptNewClient,
pserver);
if (status < 0) {
fprintf(stderr,
"iocLogServer: failed to add read callback\n");
return IOCLS_ERROR;
}
while(TRUE){
timeout.tv_sec = 60; /* 1 min */
timeout.tv_usec = 0;
fdmgr_pend_event(pserver->pfdctx, &timeout);
fflush(pserver->poutfile);
}
while (TRUE) {
timeout.tv_sec = 60; /* 1 min */
timeout.tv_usec = 0;
fdmgr_pend_event(pserver->pfdctx, &timeout);
fflush(pserver->poutfile);
}
}
/*
@@ -964,6 +965,7 @@ static int getDirectory(void)
"Problem reading o/p from `%s' because `%s'\n",
ioc_log_file_command,
strerror(errno));
(void) pclose(pipe);
return IOCLS_ERROR;
}
(void) pclose(pipe);

View File

@@ -256,6 +256,18 @@ int epicsStrPrintEscaped(FILE *fp, const char *s, size_t len)
return nout;
}
/* Until Base requires POSIX 2008 we must provide our own implementation */
size_t epicsStrnLen(const char *s, size_t maxlen)
{
size_t i;
for (i=0; i<maxlen; i++) {
if(s[i]=='\0')
return i;
}
return i;
}
int epicsStrGlobMatch(const char *str, const char *pattern)
{
const char *cp = NULL, *mp = NULL;

View File

@@ -33,6 +33,7 @@ epicsShareFunc int epicsStrnCaseCmp(const char *s1, const char *s2, size_t len);
epicsShareFunc char * epicsStrDup(const char *s);
epicsShareFunc int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n);
#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw
epicsShareFunc size_t epicsStrnLen(const char *s, size_t maxlen);
epicsShareFunc int epicsStrGlobMatch(const char *str, const char *pattern);
epicsShareFunc char * epicsStrtok_r(char *s, const char *delim, char **lasts);
epicsShareFunc unsigned int epicsStrHash(const char *str, unsigned int seed);

View File

@@ -380,7 +380,7 @@ static gtProvider * findProvider(ELLLIST *plist, epicsMutexId lock,
for (ptp = (gtProvider *)ellFirst(plist);
ptp; ptp = (gtProvider *)ellNext(&ptp->node)) {
if (ptp->priority == ptp->priority &&
if (ptp->priority == priority &&
!strcmp(ptp->name, name))
break;
}

View File

@@ -6,15 +6,15 @@
* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne
* 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.cpp */
/* Author Jeffrey O. Hill */
// Notes:
// 1) The epicsTime::nSec field is not public and so it could be
// changed to work more like the fractional seconds field in the NTP time
// stamp. That would significantly improve the precision of epicsTime on
// 1) The epicsTime::nSec field is not public and so it could be
// changed to work more like the fractional seconds field in the NTP time
// stamp. That would significantly improve the precision of epicsTime on
// 64 bit architectures.
//
@@ -26,7 +26,7 @@
#include <string.h>
#include <limits.h>
#include <float.h>
#include <string> // vxWorks 6.0 requires this include
#include <string> // vxWorks 6.0 requires this include
#define epicsExportSharedSymbols
#include "locationException.h"
@@ -37,7 +37,7 @@
#include "osiSock.h" /* pull in struct timeval */
#include "epicsStdio.h"
static const char pEpicsTimeVersion[] =
static const char pEpicsTimeVersion[] =
"@(#) " EPICS_VERSION_STRING ", Common Utilities Library " __DATE__;
//
@@ -60,11 +60,13 @@ static const unsigned long NTP_TIME_AT_EPICS_EPOCH =
//
// epicsTime (const unsigned long secIn, const unsigned long nSecIn)
//
inline epicsTime::epicsTime (const unsigned long secIn,
const unsigned long nSecIn) :
secPastEpoch ( nSecIn / nSecPerSec + secIn ),
nSec ( nSecIn % nSecPerSec )
inline epicsTime::epicsTime (const unsigned long secIn, const unsigned long nSecIn) :
secPastEpoch ( secIn ), nSec ( nSecIn )
{
if (nSecIn >= nSecPerSec) {
this->secPastEpoch += nSecIn / nSecPerSec;
this->nSec = nSecIn % nSecPerSec;
}
}
//
@@ -93,7 +95,7 @@ epicsTimeLoadTimeInit::epicsTimeLoadTimeInit ()
* the ANSI epoch (1/1/1970 00:00:00UTC)
* Convert this offset into time_t units, however this must not be
* calculated using local time (i.e. using mktime() or similar), since
* in the UK the ANSI Epoch had daylight saving time in effect, and
* in the UK the ANSI Epoch had daylight saving time in effect, and
* the value calculated would be 3600 seconds wrong.*/
this->epicsEpochOffset =
(double) POSIX_TIME_AT_EPICS_EPOCH / this->time_tSecPerTick;
@@ -103,7 +105,7 @@ epicsTimeLoadTimeInit::epicsTimeLoadTimeInit ()
this->epicsEpochOffset >= 0) {
// We can use simpler code on Posix-compliant systems
this->useDiffTimeOptimization = true;
this->epicsEpochOffsetAsAnUnsignedLong =
this->epicsEpochOffsetAsAnUnsignedLong =
static_cast<unsigned long>(this->epicsEpochOffset);
} else {
// Forced to use the slower but correct code
@@ -113,47 +115,26 @@ epicsTimeLoadTimeInit::epicsTimeLoadTimeInit ()
}
//
// epicsTime::addNanoSec ()
// private epicsTime::addNanoSec ()
//
// The nano-second field of several of the the UNIX time stamp formats
// field is stored in the C type "long".
// Most formats keep the nSec value as an unsigned long, so are +ve.
// struct timeval's tv_usec may be -1, but I think that means error,
// so this private method never needs to handle -ve offsets.
//
void epicsTime :: addNanoSec ( long nSecAdj )
{
//
// After optimizing this function we now have a larger code which
// uses only unsigned integer, and not floating point, arithmetic.
// This change benefits embedded CPU's lacking a floating point
// co-processor at the expense of some additional code to maintain.
//
// We hope that all CPU's we run on provide at least an integer
// divide instruction which should enable this implementation
// to be more efficient than implementations based on branching;
// this is presuming that we will run on pipelined architectures.
//
// Overflow and underflow is expected; in the future we might
// operate close to, the modulo of, the EPICS epic.
//
// We are depending on the normalize operation in the private
// constructor used below.
//
// joh 11-04-2012
//
if ( nSecAdj >= 0 ) {
const unsigned long nSecPlus =
static_cast <unsigned long> ( nSecAdj );
const unsigned long nSecPlusAdj = nSecPlus % nSecPerSec;
const unsigned long secPlusAdj = nSecPlus / nSecPerSec;
*this = epicsTime ( this->secPastEpoch+secPlusAdj,
this->nSec+nSecPlusAdj );
if (nSecAdj <= 0)
return;
if (static_cast<unsigned long>(nSecAdj) >= nSecPerSec) {
this->secPastEpoch += nSecAdj / nSecPerSec;
nSecAdj %= nSecPerSec;
}
else {
const unsigned long nSecMinus =
static_cast <unsigned long> ( -nSecAdj );
const unsigned long nSecMinusAdj = nSecMinus % nSecPerSec;
const unsigned long secMinusAdj = nSecMinus / nSecPerSec;
*this = epicsTime ( this->secPastEpoch - secMinusAdj - 1u,
this->nSec + nSecPerSec - nSecMinusAdj );
this->nSec += nSecAdj; // Can't overflow
if (this->nSec >= nSecPerSec) {
this->secPastEpoch++;
this->nSec -= nSecPerSec;
}
}
@@ -166,11 +147,11 @@ epicsTime::epicsTime ( const time_t_wrapper & ansiTimeTicks )
static epicsTimeLoadTimeInit & lti = * new epicsTimeLoadTimeInit ();
//
// try to directly map time_t into an unsigned long integer because this is
// try to directly map time_t into an unsigned long integer because this is
// faster on systems w/o hardware floating point and a simple integer type time_t.
//
if ( lti.useDiffTimeOptimization ) {
// LONG_MAX is used here and not ULONG_MAX because some systems (linux)
// LONG_MAX is used here and not ULONG_MAX because some systems (linux)
// still store time_t as a long.
if ( ansiTimeTicks.ts > 0 && ansiTimeTicks.ts <= LONG_MAX ) {
unsigned long ticks = static_cast < unsigned long > ( ansiTimeTicks.ts );
@@ -186,8 +167,8 @@ epicsTime::epicsTime ( const time_t_wrapper & ansiTimeTicks )
}
//
// otherwise map time_t, which ANSI C and POSIX define as any arithmetic type,
// into type double
// otherwise map time_t, which ANSI C and POSIX define as any arithmetic type,
// into type double
//
double sec = ansiTimeTicks.ts * lti.time_tSecPerTick - lti.epicsEpochOffset;
@@ -209,14 +190,14 @@ epicsTime::epicsTime ( const time_t_wrapper & ansiTimeTicks )
this->nSec = static_cast <unsigned long> ( ( sec-this->secPastEpoch ) * nSecPerSec );
}
epicsTime::epicsTime (const epicsTimeStamp &ts)
epicsTime::epicsTime (const epicsTimeStamp &ts)
{
if ( ts.nsec < nSecPerSec ) {
this->secPastEpoch = ts.secPastEpoch;
this->nSec = ts.nsec;
}
else {
throw std::logic_error (
throw std::logic_error (
"epicsTimeStamp has overflow in nano-seconds field" );
}
}
@@ -262,7 +243,7 @@ epicsTime::operator time_t_wrapper () const
return wrap;
}
}
//
// map type double into time_t which ansi C defines as some arithmetic type
//
@@ -317,20 +298,82 @@ epicsTime::operator gm_tm_nano_sec () const
//
epicsTime::epicsTime (const local_tm_nano_sec &tm)
{
static const time_t mktimeFailure = static_cast <time_t> (-1);
time_t_wrapper ansiTimeTicks;
struct tm tmp = tm.ansi_tm;
time_t_wrapper ansiTimeTicks = { mktime (&tmp) };
ansiTimeTicks.ts = mktime (&tmp);
if (ansiTimeTicks.ts == mktimeFailure) {
static const time_t mktimeError = static_cast <time_t> (-1);
if (ansiTimeTicks.ts == mktimeError) {
throwWithLocation ( formatProblemWithStructTM () );
}
*this = epicsTime (ansiTimeTicks);
*this = epicsTime(ansiTimeTicks);
this->addNanoSec(tm.nSec);
}
unsigned long nSecAdj = tm.nSec % nSecPerSec;
unsigned long secAdj = tm.nSec / nSecPerSec;
*this = epicsTime ( this->secPastEpoch+secAdj, this->nSec+nSecAdj );
//
// epicsTime (const gm_tm_nano_sec &tm)
//
// do conversion avoiding the timezone mechanism
static inline int is_leap(int year)
{
if (year % 400 == 0)
return 1;
if (year % 100 == 0)
return 0;
if (year % 4 == 0)
return 1;
return 0;
}
static inline int days_from_0(int year)
{
year--;
return 365 * year + (year / 400) - (year / 100) + (year / 4);
}
static inline int days_from_1970(int year)
{
static const int days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
static inline int days_from_1jan(int year, int month, int day)
{
static const int days[2][12] =
{
{ 0,31,59,90,120,151,181,212,243,273,304,334},
{ 0,31,60,91,121,152,182,213,244,274,305,335}
};
return days[is_leap(year)][month-1] + day - 1;
}
epicsTime::epicsTime (const gm_tm_nano_sec &tm)
{
int year = tm.ansi_tm.tm_year + 1900;
int month = tm.ansi_tm.tm_mon;
if (month > 11) {
year += month / 12;
month %= 12;
} else if (month < 0) {
int years_diff = (-month + 11) / 12;
year -= years_diff;
month += 12 * years_diff;
}
month++;
int day = tm.ansi_tm.tm_mday;
int day_of_year = days_from_1jan(year, month, day);
int days_since_epoch = days_from_1970(year) + day_of_year;
time_t_wrapper ansiTimeTicks;
ansiTimeTicks.ts = ((days_since_epoch
* 24 + tm.ansi_tm.tm_hour)
* 60 + tm.ansi_tm.tm_min)
* 60 + tm.ansi_tm.tm_sec;
*this = epicsTime(ansiTimeTicks);
this->addNanoSec(tm.nSec);
}
//
@@ -372,9 +415,9 @@ epicsTime::operator struct timeval () const
// a direct assignment. On other systems I dont know that we can
// guarantee that time_t and timeval :: tv_sec will have the
// same epoch or have the same scaling factor to discrete seconds.
// For example, on windows time_t changed recently to a 64 bit
// For example, on windows time_t changed recently to a 64 bit
// quantity but timeval is still a long. That can cause problems
// on 32 bit systems. So technically, we should have an os
// on 32 bit systems. So technically, we should have an os
// dependent conversion between time_t and timeval :: tv_sec?
ts.tv_sec = ansiTimeTicks.ts;
ts.tv_usec = static_cast < long > ( this->nSec / nSecPerUSec );
@@ -391,9 +434,9 @@ epicsTime::epicsTime (const struct timeval &ts)
// a direct assignment. On other systems I dont know that we can
// guarantee that time_t and timeval :: tv_sec will have the
// same epoch or have the same scaling factor to discrete seconds.
// For example, on windows time_t changed recently to a 64 bit
// For example, on windows time_t changed recently to a 64 bit
// quantity but timeval is still a long. That can cause problems
// on 32 bit systems. So technically, we should have an os
// on 32 bit systems. So technically, we should have an os
// dependent conversion between time_t and timeval :: tv_sec?
ansiTimeTicks.ts = ts.tv_sec;
*this = epicsTime (ansiTimeTicks);
@@ -415,7 +458,7 @@ epicsTime::operator l_fp () const
{
l_fp ts;
ts.l_ui = this->secPastEpoch + NTP_TIME_AT_EPICS_EPOCH;
ts.l_uf = static_cast < unsigned long >
ts.l_uf = static_cast < unsigned long >
( ( this->nSec * NTP_FRACTION_DENOMINATOR ) / nSecPerSec );
return ts;
}
@@ -426,14 +469,14 @@ epicsTime::operator l_fp () const
epicsTime::epicsTime ( const l_fp & ts )
{
this->secPastEpoch = ts.l_ui - NTP_TIME_AT_EPICS_EPOCH;
this->nSec = static_cast < unsigned long >
this->nSec = static_cast < unsigned long >
( ( ts.l_uf / NTP_FRACTION_DENOMINATOR ) * nSecPerSec );
}
epicsTime::operator epicsTimeStamp () const
{
if ( this->nSec >= nSecPerSec ) {
throw std::logic_error (
throw std::logic_error (
"epicsTimeStamp has overflow in nano-seconds field?" );
}
epicsTimeStamp ts;
@@ -444,7 +487,7 @@ epicsTime::operator epicsTimeStamp () const
// on 64 bit hosts than the original epicsTimeStamp::secPastEpoch. The
// epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will
// match the original network protocol. Of course one can anticipate
// that eventually, a epicsUInt64 based network time stamp will be
// that eventually, a epicsUInt64 based network time stamp will be
// introduced when 64 bit architectures are more ubiquitous.
//
// Truncation usually works fine here because the routines in this code
@@ -458,14 +501,14 @@ epicsTime::operator epicsTimeStamp () const
return ts;
}
// Break up a format string into "<strftime prefix>%0<nnn>f<postfix>"
// (where <nnn> in an unsigned integer)
// Break up a format string into "<strftime prefix>%0<nnn>f<postfix>"
// (where <nnn> in an unsigned integer)
// Result:
// A) Copies a prefix which is valid for ANSI strftime into the supplied
// buffer setting the buffer to an empty string if no prefix is present.
// B) Indicates whether a valid "%0<n>f]" is present or not and if so
// B) Indicates whether a valid "%0<n>f]" is present or not and if so
// specifying its nnnn
// C) returning a pointer to the postfix (which might be passed again
// C) returning a pointer to the postfix (which might be passed again
// to fracFormatFind.
static const char * fracFormatFind (
const char * const pFormat,
@@ -529,8 +572,8 @@ static const char * fracFormatFind (
//
// size_t epicsTime::strftime ()
//
size_t epicsTime::strftime (
char * pBuff, size_t bufLength, const char * pFormat ) const
size_t epicsTime::strftime (
char * pBuff, size_t bufLength, const char * pFormat ) const
{
if ( bufLength == 0u ) {
return 0u;
@@ -547,15 +590,15 @@ size_t epicsTime::strftime (
const char * pFmt = pFormat;
size_t bufLenLeft = bufLength;
while ( *pFmt != '\0' && bufLenLeft > 1 ) {
// look for "%0<n>f" at the end (used for fractional second formatting)
// look for "%0<n>f" at the end (used for fractional second formatting)
char strftimePrefixBuf [256];
bool fracFmtFound;
unsigned long fracWid = 0;
pFmt = fracFormatFind (
pFmt,
pFmt,
strftimePrefixBuf, sizeof ( strftimePrefixBuf ),
fracFmtFound, fracWid );
// nothing more in the string, then quit
if ( ! ( strftimePrefixBuf[0] != '\0' || fracFmtFound ) ) {
break;
@@ -657,7 +700,7 @@ void epicsTime::show ( unsigned level ) const
if ( level > 1 ) {
// this also suppresses the "defined, but not used"
// warning message
printf ( "epicsTime: revision \"%s\"\n",
printf ( "epicsTime: revision \"%s\"\n",
pEpicsTimeVersion );
}
@@ -704,10 +747,10 @@ epicsTime epicsTime::operator + (const double &rhs) const
}
//
// operator -
// operator -
//
// To make this code robust during timestamp rollover events
// time stamp differences greater than one half full scale are
// time stamp differences greater than one half full scale are
// interpreted as rollover situations:
//
// when RHS is greater than THIS:
@@ -729,7 +772,7 @@ double epicsTime::operator - (const epicsTime &rhs) const
// so the unsigned to signed conversion is ok
//
if (this->nSec>=rhs.nSec) {
nSecRes = this->nSec - rhs.nSec;
nSecRes = this->nSec - rhs.nSec;
}
else {
nSecRes = rhs.nSec - this->nSec;
@@ -746,7 +789,7 @@ double epicsTime::operator - (const epicsTime &rhs) const
if (secRes > ULONG_MAX/2) {
//
// In this situation where the difference is more than
// 68 years assume that the seconds counter has rolled
// 68 years assume that the seconds counter has rolled
// over and compute the "wrap around" difference
//
secRes = 1 + (ULONG_MAX-secRes);
@@ -761,7 +804,7 @@ double epicsTime::operator - (const epicsTime &rhs) const
if (secRes > ULONG_MAX/2) {
//
// In this situation where the difference is more than
// 68 years assume that the seconds counter has rolled
// 68 years assume that the seconds counter has rolled
// over and compute the "wrap around" difference
//
secRes = 1 + (ULONG_MAX-secRes);
@@ -770,7 +813,7 @@ double epicsTime::operator - (const epicsTime &rhs) const
}
}
return secRes + nSecRes/nSecPerSec;
return secRes + nSecRes/nSecPerSec;
}
//
@@ -791,7 +834,7 @@ bool epicsTime::operator <= (const epicsTime &rhs) const
else {
//
// In this situation where the difference is more than
// 69 years assume that the seconds counter has rolled
// 69 years assume that the seconds counter has rolled
// over and compute the "wrap around" result
//
rc = false;
@@ -808,7 +851,7 @@ bool epicsTime::operator <= (const epicsTime &rhs) const
else {
//
// In this situation where the difference is more than
// 69 years assume that the seconds counter has rolled
// 69 years assume that the seconds counter has rolled
// over and compute the "wrap around" result
//
rc = true;
@@ -843,7 +886,7 @@ bool epicsTime::operator < (const epicsTime &rhs) const
else {
//
// In this situation where the difference is more than
// 69 years assume that the seconds counter has rolled
// 69 years assume that the seconds counter has rolled
// over and compute the "wrap around" result
//
rc = false;
@@ -860,7 +903,7 @@ bool epicsTime::operator < (const epicsTime &rhs) const
else {
//
// In this situation where the difference is more than
// 69 years assume that the seconds counter has rolled
// 69 years assume that the seconds counter has rolled
// over and compute the "wrap around" result
//
rc = true;
@@ -881,7 +924,7 @@ extern "C" {
//
// ANSI C interface
//
// its too bad that these cant be implemented with inline functions
// its too bad that these cant be implemented with inline functions
// at least when running the GNU compiler
//
epicsShareFunc int epicsShareAPI epicsTimeToTime_t (time_t *pDest, const epicsTimeStamp *pSrc)
@@ -944,6 +987,19 @@ extern "C" {
}
return epicsTimeOK;
}
epicsShareFunc int epicsShareAPI epicsTimeFromGMTM (epicsTimeStamp *pDest, const struct tm *pSrc, unsigned long nSecSrc)
{
try {
gm_tm_nano_sec tmns;
tmns.ansi_tm = *pSrc;
tmns.nSec = nSecSrc;
*pDest = epicsTime (tmns);
}
catch (...) {
return S_time_conversion;
}
return epicsTimeOK;
}
epicsShareFunc int epicsShareAPI epicsTimeToTimespec (struct timespec *pDest, const epicsTimeStamp *pSrc)
{
try {
@@ -1075,4 +1131,3 @@ extern "C" {
}
}
}

View File

@@ -106,10 +106,12 @@ public:
epicsTime & operator = ( const local_tm_nano_sec & );
/*
* convert to ANSI Cs "struct tm" (with nano seconds)
* convert to and from ANSI Cs "struct tm" (with nano seconds)
* adjusted for GM time (UTC)
*/
operator gm_tm_nano_sec () const;
epicsTime ( const gm_tm_nano_sec & );
epicsTime & operator = ( const gm_tm_nano_sec & );
/* convert to and from POSIX RTs "struct timespec" */
operator struct timespec () const;
@@ -201,13 +203,15 @@ epicsShareFunc int epicsShareAPI epicsTimeToTime_t (
epicsShareFunc int epicsShareAPI epicsTimeFromTime_t (
epicsTimeStamp * pDest, time_t src );
/*convert to and from ANSI C's "struct tm" with nano seconds */
/* convert to and from ANSI C's "struct tm" with nano seconds */
epicsShareFunc int epicsShareAPI epicsTimeToTM (
struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc );
epicsShareFunc int epicsShareAPI epicsTimeToGMTM (
struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc );
epicsShareFunc int epicsShareAPI epicsTimeFromTM (
epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc );
epicsShareFunc int epicsShareAPI epicsTimeFromGMTM (
epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc );
/* convert to and from POSIX RT's "struct timespec" */
epicsShareFunc int epicsShareAPI epicsTimeToTimespec (
@@ -319,6 +323,11 @@ inline epicsTime & epicsTime::operator = ( const local_tm_nano_sec & rhs )
return *this = epicsTime ( rhs );
}
inline epicsTime & epicsTime::operator = ( const gm_tm_nano_sec & rhs )
{
return *this = epicsTime ( rhs );
}
inline epicsTime & epicsTime::operator = ( const struct timespec & rhs )
{
*this = epicsTime ( rhs );

View File

@@ -1,7 +1,7 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* 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: Eric Norum
@@ -38,6 +38,7 @@ typedef socklen_t osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
/*
@@ -42,6 +42,7 @@ typedef socklen_t osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -72,4 +73,3 @@ typedef socklen_t osiSocklen_t;
#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name))
#endif /*osdSockH*/

View File

@@ -171,7 +171,7 @@ static int receiveMessage(
return -1;
}
rsize = receiveMessage(id, id->localBuf, id->maxSize, wait, delay);
if ((rsize < 0) || (rsize > size))
if (rsize > size)
return -1;
memcpy(buffer, id->localBuf, rsize);
}

View File

@@ -1,7 +1,7 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* 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.
\*************************************************************************/
/*
* RTEMS osdSock.h
@@ -35,7 +35,7 @@ int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, str
#ifdef __cplusplus
}
#endif
typedef int SOCKET;
#define INVALID_SOCKET (-1)
#define SOCKERRNO errno
@@ -49,6 +49,7 @@ typedef socklen_t osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -75,7 +76,7 @@ typedef socklen_t osiSocklen_t;
#ifndef INADDR_NONE
# define INADDR_NONE (0xffffffff)
#endif
#endif
/*
* For shutdown()

View File

@@ -427,8 +427,6 @@ void epicsThreadGetName (epicsThreadId id, char *name, size_t size)
struct taskVar *v;
int haveName = 0;
if (size <= 0)
return;
taskVarLock ();
for (v=taskVarHead ; v != NULL ; v=v->forw) {
if (v->id == tid) {
@@ -690,6 +688,7 @@ void epicsThreadShow (epicsThreadId id, unsigned int level)
for (v = taskVarHead ; v != NULL ; v = v->forw) {
if ((rtems_id)id == v->id) {
epicsThreadShowInfo (v, level);
taskVarUnlock ();
return;
}
}

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
#ifndef osdSockH
@@ -14,7 +14,7 @@
#include <errno.h>
/*
* winsock2.h changes the structure alignment to 4 if
* winsock2.h changes the structure alignment to 4 if
* WIN32 isnt set which can be a source of confusion
*/
#ifndef WIN32
@@ -48,6 +48,7 @@ typedef int osiSocklen_t;
#define SOCK_ENOBUFS WSAENOBUFS
#define SOCK_ECONNRESET WSAECONNRESET
#define SOCK_ETIMEDOUT WSAETIMEDOUT
#define SOCK_EACCES WSAEACCES
#define SOCK_EADDRINUSE WSAEADDRINUSE
#define SOCK_EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define SOCK_ECONNREFUSED WSAECONNREFUSED

View File

@@ -523,13 +523,8 @@ static win32ThreadParam * epicsThreadParmCreate ( const char *pName )
pParmWIN32 = calloc ( 1, sizeof ( *pParmWIN32 ) + strlen ( pName ) + 1 );
if ( pParmWIN32 ) {
if ( pName ) {
pParmWIN32->pName = (char *) ( pParmWIN32 + 1 );
strcpy ( pParmWIN32->pName, pName );
}
else {
pParmWIN32->pName = 0;
}
pParmWIN32->pName = (char *) ( pParmWIN32 + 1 );
strcpy ( pParmWIN32->pName, pName );
pParmWIN32->isSuspended = 0;
}
return pParmWIN32;

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
/*
* cygwin32 specific include
@@ -49,6 +49,7 @@ typedef int osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -67,4 +68,3 @@ typedef int osiSocklen_t;
#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name))
#endif /*osdSockH*/

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
#ifndef osdSockH
@@ -29,7 +29,7 @@
#define IPPORT_USERRESERVED 5000
#endif
typedef int SOCKET;
#define INVALID_SOCKET (-1)
#define SOCKERRNO errno
@@ -43,6 +43,7 @@ typedef socklen_t osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -77,4 +78,3 @@ typedef socklen_t osiSocklen_t;
#endif
#endif /*osdSockH*/

View File

@@ -39,6 +39,7 @@ typedef socklen_t osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
/*
@@ -39,7 +39,7 @@ typedef int osiSockIoctl_t;
#if SOLARIS > 6 || defined ( _SOCKLEN_T )
typedef uint32_t osiSocklen_t;
#else
#else
typedef int osiSocklen_t;
#endif
@@ -51,6 +51,7 @@ typedef int osiSockIoctl_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -80,9 +81,8 @@ typedef int osiSockIoctl_t;
#ifndef INADDR_NONE
# define INADDR_NONE (0xffffffff)
#endif
#endif
#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name))
#endif /*osdSockH*/

View File

@@ -4,7 +4,7 @@
* 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.
\*************************************************************************/
/*
* vxWorks specific socket include
@@ -44,7 +44,7 @@ int sysClkRateGet(void);
#ifdef __cplusplus
}
#endif
typedef int SOCKET;
#define INVALID_SOCKET (-1)
#define SOCKERRNO errno
@@ -72,6 +72,7 @@ typedef int osiSocklen_t;
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
@@ -93,7 +94,7 @@ typedef int osiSocklen_t;
#ifndef INADDR_NONE
# define INADDR_NONE (0xffffffff)
#endif
#endif
#if defined(_SIZEOF_ADDR_IFREQ)
# define ifreq_size(pifreq) _SIZEOF_ADDR_IFREQ(*pifreq)
@@ -104,5 +105,3 @@ typedef int osiSocklen_t;
#endif
#endif /*osdSockH*/

View File

@@ -1,4 +1,5 @@
/*************************************************************************\
* Copyright (c) 2016 Michael Davidsaver
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
@@ -11,6 +12,7 @@
#include <stdlib.h>
#include "ellLib.h"
#include "dbDefs.h"
#include "epicsUnitTest.h"
#include "testMain.h"
@@ -20,15 +22,13 @@ struct myItem {
int num;
};
MAIN(epicsEllTest)
static void testList(void)
{
ELLLIST list1;
ELLLIST list2 = ELLLIST_INIT;
int i1 = 1;
struct myItem *pitem, *pfirst, *pick;
testPlan(70);
list1.count = 27;
list1.node.next = (ELLNODE *) 0x01010101;
list1.node.previous = (ELLNODE *) 0x10101010;
@@ -192,6 +192,77 @@ MAIN(epicsEllTest)
ellFree2(&list1, free);
testOk1(ellCount(&list1) == 0);
}
typedef struct { int A, B; } input_t;
static int myItemCmp(const ELLNODE *a, const ELLNODE *b)
{
struct myItem *A = CONTAINER(a, struct myItem, node),
*B = CONTAINER(b, struct myItem, node);
if (A->num < B->num) return -1;
else if(A->num > B->num) return 1;
else if(A->list < B->list) return -1;
else if(A->list > B->list) return 1;
else return 0;
}
static const input_t input[] = {
{-4, 0},
{-5, 0},
{0,0},
{50,0},
{0,1},
{5,0},
{5,1}
};
static
void testSort(const input_t *inp, size_t ninp)
{
unsigned i;
ELLLIST list = ELLLIST_INIT;
struct myItem *alloc = calloc(ninp, sizeof(*alloc));
if(!alloc) testAbort("testSort allocation fails");
for(i=0; i<ninp; i++) {
struct myItem *it = &alloc[i];
it->num = inp[i].A;
it->list= inp[i].B;
ellAdd(&list, &it->node);
}
ellSortStable(&list, &myItemCmp);
testOk(ellCount(&list)==ninp, "output length %u == %u", (unsigned)ellCount(&list), (unsigned)ninp);
if(ellCount(&list)==0) {
testSkip(ninp-1, "all items lost");
}
{
struct myItem *prev = CONTAINER(ellFirst(&list), struct myItem, node),
*next;
for(next = CONTAINER(ellNext(&prev->node), struct myItem, node);
next;
prev = next, next = CONTAINER(ellNext(&next->node), struct myItem, node))
{
int cond = (prev->num<next->num) || (prev->num==next->num && prev->list<next->list);
testOk(cond, "%d:%d < %d:%d", prev->num, prev->list, next->num, next->list);
}
}
}
MAIN(epicsEllTest)
{
testPlan(77);
testList();
testSort(input, NELEMENTS(input));
return testDone();
}

View File

@@ -250,5 +250,12 @@ MAIN(epicsEventTest)
eventWaitTest();
eventWakeupTest();
free(name);
free(id);
epicsRingPointerDelete(pinfo->ring);
epicsMutexDestroy(pinfo->lockRing);
epicsEventDestroy(event);
free(pinfo);
return testDone();
}

View File

@@ -279,5 +279,11 @@ MAIN(epicsMutexTest)
epicsMutexPerformance ();
free(pinfo);
free(arg);
free(name);
free(id);
epicsMutexDestroy(mutex);
return testDone();
}

View File

@@ -37,7 +37,14 @@ static void testEpicsSnprintf(void) {
const char *expected = exbuffer;
int size;
int rtn, rlen;
#ifdef _WIN32
#if (defined(_MSC_VER) && _MSC_VER < 1900) || \
(defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT))
_set_output_format(_TWO_DIGIT_EXPONENT);
#endif
#endif
sprintf(exbuffer, format, ivalue, fvalue, svalue);
rlen = strlen(expected)+1;
@@ -121,11 +128,7 @@ void testStdoutRedir (const char *report)
MAIN(epicsStdioTest)
{
#ifdef _WIN32
testPlan(166);
#else
testPlan(163);
#endif
testEpicsSnprintf();
#ifdef __rtems__
/* ensure there is a writeable area */

View File

@@ -87,7 +87,7 @@ MAIN(epicsStringTest)
char *s;
int status;
testPlan(402);
testPlan(406);
testChars();
@@ -122,6 +122,11 @@ MAIN(epicsStringTest)
testOk1(epicsStrHash(abcd, 0) == epicsMemHash(abcde, 4, 0));
testOk1(epicsStrHash(abcd, 0) != epicsMemHash("abcd\0", 5, 0));
testOk1(epicsStrnLen("abcd", 5)==4);
testOk1(epicsStrnLen("abcd", 4)==4);
testOk1(epicsStrnLen("abcd", 3)==3);
testOk1(epicsStrnLen("abcd", 0)==0);
testGlob();
memset(result, 'x', sizeof(result));

View File

@@ -43,7 +43,7 @@ MAIN(epicsTimeTest)
const int wasteTime = 100000;
const int nTimes = 10;
testPlan(15 + nTimes * 18);
testPlan(15 + nTimes * 19);
try {
const epicsTimeStamp epochTS = {0, 0};
@@ -200,6 +200,11 @@ MAIN(epicsTimeTest)
epicsTime beginANSI = ansiDate;
testOk1(beginANSI + diff == now);
// test struct gmtm round-trip conversion
gm_tm_nano_sec ansiGmDate = begin;
epicsTime beginGMANSI = ansiGmDate;
testOk1(beginGMANSI + diff == now);
// test struct timespec round-trip conversion
struct timespec ts = begin;
epicsTime beginTS = ts;

View File

@@ -115,5 +115,9 @@ MAIN(ringBytesTest)
testOk(n==1, "ring get %d", 1);
check(ring, RINGSIZE);
epicsRingBytesDelete(ring);
epicsEventDestroy(consumerEvent);
free(pinfo);
return testDone();
}