Merged changes from Base-3.14, to revno 12613

This commit is contained in:
Andrew Johnson
2016-02-25 14:13:40 -06:00
15 changed files with 347 additions and 273 deletions
+10 -2
View File
@@ -264,19 +264,27 @@ void cast_server(void *pParm)
if(prsrv_cast_client->recv.cnt !=
prsrv_cast_client->recv.stk){
char buf[40];
ipAddrToDottedIP (&prsrv_cast_client->addr, buf, sizeof(buf));
epicsPrintf ("CAS: partial (damaged?) UDP msg of %d bytes from %s ?\n",
prsrv_cast_client->recv.cnt-prsrv_cast_client->recv.stk, buf);
epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S",
&prsrv_cast_client->time_at_last_recv);
epicsPrintf ("CAS: message received at %s\n", buf);
}
}
else {
char buf[40];
ipAddrToDottedIP (&prsrv_cast_client->addr, buf, sizeof(buf));
epicsPrintf ("CAS: invalid (damaged?) UDP request from %s ?\n", buf);
epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S",
&prsrv_cast_client->time_at_last_recv);
epicsPrintf ("CAS: message received at %s\n", buf);
}
if (CASDEBUG>2) {
+32 -13
View File
@@ -33,6 +33,10 @@ static int cond_search(const char **ppinst, int match);
#define PI 3.14159265358979323
#endif
/* Turn off global optimization for 64-bit MSVC builds */
#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW)
# pragma optimize("g", off)
#endif
/* calcPerform
*
@@ -45,6 +49,7 @@ epicsShareFunc long
double *ptop; /* stack pointer */
double top; /* value from top of stack */
epicsInt32 itop; /* integer from top of stack */
epicsUInt32 utop; /* unsigned integer from top of stack */
int op;
int nargs;
@@ -262,7 +267,7 @@ epicsShareFunc long
case NINT:
top = *ptop;
*ptop = (double)(epicsInt32)(top >= 0 ? top + 0.5 : top - 0.5);
*ptop = (epicsInt32) (top >= 0 ? top + 0.5 : top - 0.5);
break;
case RANDOM:
@@ -283,34 +288,45 @@ epicsShareFunc long
*ptop = ! *ptop;
break;
/* For bitwise operations on values with bit 31 set, double values
* must first be cast to unsigned to correctly set that bit; the
* double value must be negative in that case. The result must be
* cast to a signed integer before converting to the double result.
*/
case BIT_OR:
itop = (epicsInt32) *ptop--;
*ptop = (epicsInt32) *ptop | itop;
utop = *ptop--;
*ptop = (epicsInt32) ((epicsUInt32) *ptop | utop);
break;
case BIT_AND:
itop = (epicsInt32) *ptop--;
*ptop = (epicsInt32) *ptop & itop;
utop = *ptop--;
*ptop = (epicsInt32) ((epicsUInt32) *ptop & utop);
break;
case BIT_EXCL_OR:
itop = (epicsInt32) *ptop--;
*ptop = (epicsInt32) *ptop ^ itop;
utop = *ptop--;
*ptop = (epicsInt32) ((epicsUInt32) *ptop ^ utop);
break;
case BIT_NOT:
itop = (epicsInt32) *ptop;
*ptop = ~itop;
utop = *ptop;
*ptop = (epicsInt32) ~utop;
break;
/* The shift operators use signed integers, so a right-shift will
* extend the sign bit into the left-hand end of the value. The
* double-casting through unsigned here is important, see above.
*/
case RIGHT_SHIFT:
itop = (epicsInt32) *ptop--;
*ptop = (epicsInt32) *ptop >> itop;
utop = *ptop--;
*ptop = ((epicsInt32) (epicsUInt32) *ptop) >> (utop & 31);
break;
case LEFT_SHIFT:
itop = (epicsInt32) *ptop--;
*ptop = (epicsInt32) *ptop << itop;
utop = *ptop--;
*ptop = ((epicsInt32) (epicsUInt32) *ptop) << (utop & 31);
break;
case NOT_EQ:
@@ -367,6 +383,9 @@ epicsShareFunc long
*presult = *ptop;
return 0;
}
#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW)
# pragma optimize("", on)
#endif
epicsShareFunc long
+3 -3
View File
@@ -251,7 +251,7 @@ epicsShareFunc long
goto bad;
}
psrc = pnext;
lit_i = (int) lit_d;
lit_i = (epicsInt32) lit_d;
if (lit_d != (double) lit_i) {
*pout++ = pel->code;
memcpy(pout, &lit_d, sizeof(double));
@@ -272,8 +272,8 @@ epicsShareFunc long
}
psrc = pnext;
*pout++ = LITERAL_INT;
memcpy(pout, &lit_ui, sizeof(epicsInt32));
pout += sizeof(epicsInt32);
memcpy(pout, &lit_ui, sizeof(epicsUInt32));
pout += sizeof(epicsUInt32);
}
operand_needed = FALSE;
+12 -66
View File
@@ -81,7 +81,6 @@ template class tsFreeList
extern "C" {
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
static void ipAddrToAsciiEngineShutdownRequest ( void * );
}
// - this class executes the synchronous DNS query
@@ -107,10 +106,7 @@ private:
unsigned cancelPendingCount;
bool exitFlag;
bool callbackInProgress;
static epicsMutex * pGlobalMutex;
static ipAddrToAsciiEnginePrivate * pEngine;
static unsigned numberOfReferences;
static bool shutdownRequest;
ipAddrToAsciiTransaction & createTransaction ();
void release ();
void run ();
@@ -118,15 +114,11 @@ private:
ipAddrToAsciiEnginePrivate & operator = ( const ipAddrToAsciiEngine & );
friend class ipAddrToAsciiEngine;
friend class ipAddrToAsciiTransactionPrivate;
friend void ipAddrToAsciiEngineShutdownRequest ( void * );
friend void ipAddrToAsciiEngineGlobalMutexConstruct ( void * );
};
epicsMutex * ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
ipAddrToAsciiEnginePrivate * ipAddrToAsciiEnginePrivate :: pEngine = 0;
unsigned ipAddrToAsciiEnginePrivate :: numberOfReferences = 0u;
bool ipAddrToAsciiEnginePrivate :: shutdownRequest = false;
static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = 0;
static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = EPICS_THREAD_ONCE_INIT;
// the users are not required to supply a show routine
// for there transaction callback class
@@ -137,26 +129,13 @@ ipAddrToAsciiCallBack::~ipAddrToAsciiCallBack () {}
ipAddrToAsciiTransaction::~ipAddrToAsciiTransaction () {}
ipAddrToAsciiEngine::~ipAddrToAsciiEngine () {}
static void ipAddrToAsciiEngineShutdownRequest ( void * )
{
bool deleteGlobalMutexCondDetected = false;
{
epicsGuard < epicsMutex >
guard ( * ipAddrToAsciiEnginePrivate :: pGlobalMutex );
ipAddrToAsciiEnginePrivate :: shutdownRequest = true;
deleteGlobalMutexCondDetected =
( ipAddrToAsciiEnginePrivate :: numberOfReferences == 0 );
}
if ( deleteGlobalMutexCondDetected ) {
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
}
}
static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * )
{
ipAddrToAsciiEnginePrivate :: pGlobalMutex = newEpicsMutex;
epicsAtExit ( ipAddrToAsciiEngineShutdownRequest, 0 );
try {
ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiEnginePrivate ();
} catch (std::exception& e) {
errlogPrintf("ipAddrToAsciiEnginePrivate ctor fails with: %s\n", e.what());
}
}
// for now its probably sufficent to allocate one
@@ -168,21 +147,8 @@ ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate ()
epicsThreadOnce (
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
// since we must not own lock when checking this flag
// this diagnostic has imperfect detection, but never
// incorrect detection
if ( ipAddrToAsciiEnginePrivate :: shutdownRequest ) {
throw std :: runtime_error (
"ipAddrToAsciiEngine::allocate (): "
"attempts to create an "
"ipAddrToAsciiEngine while the exit "
"handlers are running are rejected");
}
epicsGuard < epicsMutex > guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
if ( ! ipAddrToAsciiEnginePrivate::pEngine ) {
ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiEnginePrivate ();
}
ipAddrToAsciiEnginePrivate::numberOfReferences++;
if(!ipAddrToAsciiEnginePrivate::pEngine)
throw std::runtime_error("ipAddrToAsciiEngine::allocate fails");
return * ipAddrToAsciiEnginePrivate::pEngine;
}
@@ -206,32 +172,8 @@ ipAddrToAsciiEnginePrivate::~ipAddrToAsciiEnginePrivate ()
this->thread.exitWait ();
}
// for now its probably sufficient to allocate one
// DNS transaction thread for all codes sharing
// the same process that need DNS services but we
// leave our options open for the future
void ipAddrToAsciiEnginePrivate::release ()
{
bool deleteGlobalMutexCondDetected = false;
epicsThreadOnce (
& ipAddrToAsciiEngineGlobalMutexOnceFlag,
ipAddrToAsciiEngineGlobalMutexConstruct, 0 );
{
epicsGuard < epicsMutex >
guard ( * ipAddrToAsciiEnginePrivate::pGlobalMutex );
assert ( ipAddrToAsciiEnginePrivate::numberOfReferences > 0u );
ipAddrToAsciiEnginePrivate::numberOfReferences--;
if ( ipAddrToAsciiEnginePrivate::numberOfReferences == 0u ) {
deleteGlobalMutexCondDetected =
ipAddrToAsciiEnginePrivate :: shutdownRequest;
delete ipAddrToAsciiEnginePrivate :: pEngine;
ipAddrToAsciiEnginePrivate :: pEngine = 0;
}
}
if ( deleteGlobalMutexCondDetected ) {
delete ipAddrToAsciiEnginePrivate :: pGlobalMutex;
ipAddrToAsciiEnginePrivate :: pGlobalMutex = 0;
}
}
void ipAddrToAsciiEnginePrivate::show ( unsigned level ) const
@@ -365,6 +307,8 @@ ipAddrToAsciiTransactionPrivate::~ipAddrToAsciiTransactionPrivate ()
if ( this->engine.pCurrent == this &&
this->engine.callbackInProgress &&
! this->engine.thread.isCurrentThread() ) {
// cancel from another thread while callback in progress
// waits for callback to complete
assert ( this->engine.cancelPendingCount < UINT_MAX );
this->engine.cancelPendingCount++;
{
@@ -382,9 +326,11 @@ ipAddrToAsciiTransactionPrivate::~ipAddrToAsciiTransactionPrivate ()
}
else {
if ( this->engine.pCurrent == this ) {
// cancel from callback, or while lookup in progress
this->engine.pCurrent = 0;
}
else {
// cancel before lookup starts
this->engine.labor.remove ( *this );
}
this->pending = false;
+13 -130
View File
@@ -124,148 +124,31 @@ static int osdTimeGetCurrent ( epicsTimeStamp *pDest )
return epicsTimeOK;
}
inline void UnixTimeToFileTime ( const time_t * pAnsiTime, LPFILETIME pft )
{
LONGLONG ll = Int32x32To64 ( *pAnsiTime, 10000000 ) + 116444736000000000LL;
pft->dwLowDateTime = static_cast < DWORD > ( ll );
pft->dwHighDateTime = static_cast < DWORD > ( ll >>32 );
}
static int daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31,
31, 30, 31, 30, 31 };
static bool isLeapYear ( DWORD year )
{
if ( (year % 4) == 0 ) {
return ( ( year % 100 ) != 0 || ( year % 400 ) == 0 );
} else {
return false;
}
}
static int dayOfYear ( DWORD day, DWORD month, DWORD year )
{
DWORD nDays = 0;
for ( unsigned m = 1; m < month; m++ ) {
nDays += daysInMonth[m-1];
if ( m == 2 && isLeapYear(year) ) {
nDays++;
}
}
return nDays + day;
}
// synthesize a reentrant gmtime on WIN32
int epicsShareAPI epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM )
{
FILETIME ft;
UnixTimeToFileTime ( pAnsiTime, &ft );
SYSTEMTIME st;
BOOL status = FileTimeToSystemTime ( &ft, &st );
if ( ! status ) {
return epicsTimeERROR;
struct tm * pRet = gmtime ( pAnsiTime );
if ( pRet ) {
*pTM = *pRet;
return epicsTimeOK;
}
else {
return errno;
}
pTM->tm_sec = st.wSecond; // seconds after the minute - [0,59]
pTM->tm_min = st.wMinute; // minutes after the hour - [0,59]
pTM->tm_hour = st.wHour; // hours since midnight - [0,23]
assert ( st.wDay >= 1 && st.wDay <= 31 );
pTM->tm_mday = st.wDay; // day of the month - [1,31]
assert ( st.wMonth >= 1 && st.wMonth <= 12 );
pTM->tm_mon = st.wMonth - 1; // months since January - [0,11]
assert ( st.wYear >= 1900 );
pTM->tm_year = st.wYear - 1900; // years since 1900
pTM->tm_wday = st.wDayOfWeek; // days since Sunday - [0,6]
pTM->tm_yday = dayOfYear ( st.wDay, st.wMonth, st.wYear ) - 1;
pTM->tm_isdst = 0;
return epicsTimeOK;
}
// synthesize a reentrant localtime on WIN32
int epicsShareAPI epicsTime_localtime (
const time_t * pAnsiTime, struct tm * pTM )
{
FILETIME ft;
UnixTimeToFileTime ( pAnsiTime, & ft );
TIME_ZONE_INFORMATION tzInfo;
DWORD tzStatus = GetTimeZoneInformation ( & tzInfo );
if ( tzStatus == TIME_ZONE_ID_INVALID ) {
return epicsTimeERROR;
struct tm * pRet = localtime ( pAnsiTime );
if ( pRet ) {
*pTM = *pRet;
return epicsTimeOK;
}
//
// There are remarkable weaknesses in the FileTimeToLocalFileTime
// interface so we don't use it here. Unfortunately, there is no
// corresponding function that works on file time.
//
SYSTEMTIME st;
BOOL success = FileTimeToSystemTime ( & ft, & st );
if ( ! success ) {
return epicsTimeERROR;
else {
return errno;
}
SYSTEMTIME lst;
success = SystemTimeToTzSpecificLocalTime (
& tzInfo, & st, & lst );
if ( ! success ) {
return epicsTimeERROR;
}
//
// We must convert back to file time so that we can determine if DST
// is active...
//
FILETIME lft;
success = SystemTimeToFileTime ( & lst, & lft );
if ( ! success ) {
return epicsTimeERROR;
}
int is_dst = -1; // unknown state of dst
if ( tzStatus != TIME_ZONE_ID_UNKNOWN &&
tzInfo.StandardDate.wMonth != 0 &&
tzInfo.DaylightDate.wMonth != 0) {
// determine if the specified date is
// in daylight savings time
tzInfo.StandardDate.wYear = st.wYear;
FILETIME StandardDateFT;
success = SystemTimeToFileTime (
& tzInfo.StandardDate, & StandardDateFT );
if ( ! success ) {
return epicsTimeERROR;
}
tzInfo.DaylightDate.wYear = st.wYear;
FILETIME DaylightDateFT;
success = SystemTimeToFileTime (
& tzInfo.DaylightDate, & DaylightDateFT );
if ( ! success ) {
return epicsTimeERROR;
}
if ( CompareFileTime ( & lft, & DaylightDateFT ) >= 0
&& CompareFileTime ( & lft, & StandardDateFT ) < 0 ) {
is_dst = 1;
}
else {
is_dst = 0;
}
}
pTM->tm_sec = lst.wSecond; // seconds after the minute - [0,59]
pTM->tm_min = lst.wMinute; // minutes after the hour - [0,59]
pTM->tm_hour = lst.wHour; // hours since midnight - [0,23]
assert ( lst.wDay >= 1 && lst.wDay <= 31 );
pTM->tm_mday = lst.wDay; // day of the month - [1,31]
assert ( lst.wMonth >= 1 && lst.wMonth <= 12 );
pTM->tm_mon = lst.wMonth - 1; // months since January - [0,11]
assert ( lst.wYear >= 1900 );
pTM->tm_year = lst.wYear - 1900; // years since 1900
pTM->tm_wday = lst.wDayOfWeek; // days since Sunday - [0,6]
pTM->tm_yday = dayOfYear ( lst.wDay, lst.wMonth, lst.wYear ) - 1;
pTM->tm_isdst = is_dst;
return epicsTimeOK;
}
currentTime::currentTime () :
+4
View File
@@ -96,6 +96,10 @@ epicsTimeTest_SRCS += epicsTimeTest.cpp
testHarness_SRCS += epicsTimeTest.cpp
TESTS += epicsTimeTest
TESTPROD_HOST += epicsTimeZoneTest
epicsTimeZoneTest_SRCS += epicsTimeZoneTest.c
TESTS += epicsTimeZoneTest
TESTPROD_HOST += epicsThreadTest
epicsThreadTest_SRCS += epicsThreadTest.cpp
testHarness_SRCS += epicsThreadTest.cpp
+88 -16
View File
@@ -8,6 +8,7 @@
// Author: Andrew Johnson
#include "epicsUnitTest.h"
#include "epicsTypes.h"
#include "epicsMath.h"
#include "epicsAlgorithm.h"
#include "postfix.h"
@@ -38,32 +39,59 @@ void testCalc(const char *expr, double expected) {
/* Evaluate expression, test against expected result */
bool pass = false;
double args[CALCPERFORM_NARGS] = {
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0
};
char rpn[MAX_POSTFIX_SIZE];
short err;
double result = 0.0;
result /= result; /* Start as NaN */
if (postfix(expr, rpn, &err)) {
testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr);
testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr);
} else
if (calcPerform(args, &result, rpn) && finite(result)) {
testDiag("calcPerform: error evaluating '%s'", expr);
}
if (calcPerform(args, &result, rpn) && finite(result)) {
testDiag("calcPerform: error evaluating '%s'", expr);
}
if (finite(expected) && finite(result)) {
pass = fabs(expected - result) < 1e-8;
pass = fabs(expected - result) < 1e-8;
} else if (isnan(expected)) {
pass = (bool) isnan(result);
pass = (bool) isnan(result);
} else {
pass = (result == expected);
pass = (result == expected);
}
if (!testOk(pass, "%s", expr)) {
testDiag("Expected result is %g, actually got %g", expected, result);
calcExprDump(rpn);
testDiag("Expected result is %g, actually got %g", expected, result);
calcExprDump(rpn);
}
}
void testUInt32Calc(const char *expr, epicsUInt32 expected) {
/* Evaluate expression, test against expected result */
bool pass = false;
double args[CALCPERFORM_NARGS] = {
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0
};
char rpn[MAX_POSTFIX_SIZE];
short err;
epicsUInt32 uresult;
double result = 0.0;
result /= result; /* Start as NaN */
if (postfix(expr, rpn, &err)) {
testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr);
} else
if (calcPerform(args, &result, rpn) && finite(result)) {
testDiag("calcPerform: error evaluating '%s'", expr);
}
uresult = (epicsUInt32) result;
pass = (uresult == expected);
if (!testOk(pass, "%s", expr)) {
testDiag("Expected result is 0x%x (%u), actually got 0x%x (%u)",
expected, expected, uresult, uresult);
calcExprDump(rpn);
}
return;
}
void testArgs(const char *expr, unsigned long einp, unsigned long eout) {
@@ -238,8 +266,8 @@ MAIN(epicsCalcTest)
const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0,
g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0;
testPlan(577);
testPlan(613);
/* LITERAL_OPERAND elements */
testExpr(0);
testExpr(1);
@@ -883,7 +911,51 @@ MAIN(epicsCalcTest)
testBadExpr("1?", CALC_ERR_CONDITIONAL);
testBadExpr("1?1", CALC_ERR_CONDITIONAL);
testBadExpr(":1", CALC_ERR_SYNTAX);
// Bit manipulations wrt bit 31 (bug lp:1514520)
// using integer literals
testUInt32Calc("0xaaaaaaaa AND 0xffff0000", 0xaaaa0000u);
testUInt32Calc("0xaaaaaaaa OR 0xffff0000", 0xffffaaaau);
testUInt32Calc("0xaaaaaaaa XOR 0xffff0000", 0x5555aaaau);
testUInt32Calc("~0xaaaaaaaa", 0x55555555u);
testUInt32Calc("~~0xaaaaaaaa", 0xaaaaaaaau);
testUInt32Calc("0xaaaaaaaa >> 8", 0xffaaaaaau);
testUInt32Calc("0xaaaaaaaa << 8", 0xaaaaaa00u);
// using integer literals assigned to variables
testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a AND b", 0xaaaa0000u);
testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a OR b", 0xffffaaaau);
testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a XOR b", 0x5555aaaau);
testUInt32Calc("a:=0xaaaaaaaa; ~a", 0x55555555u);
testUInt32Calc("a:=0xaaaaaaaa; ~~a", 0xaaaaaaaau);
testUInt32Calc("a:=0xaaaaaaaa; a >> 8", 0xffaaaaaau);
testUInt32Calc("a:=0xaaaaaaaa; a << 8", 0xaaaaaa00u);
// Test proper conversion of double values (+ 0.1 enforces double literal)
// when used as inputs to the bitwise operations.
// 0xaaaaaaaa = -1431655766 or 2863311530u
testUInt32Calc("-1431655766.1 OR 0", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 OR 0", 0xaaaaaaaau);
testUInt32Calc("0 OR -1431655766.1", 0xaaaaaaaau);
testUInt32Calc("0 OR 2863311530.1", 0xaaaaaaaau);
testUInt32Calc("-1431655766.1 XOR 0", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 XOR 0", 0xaaaaaaaau);
testUInt32Calc("0 XOR -1431655766.1", 0xaaaaaaaau);
testUInt32Calc("0 XOR 2863311530.1", 0xaaaaaaaau);
testUInt32Calc("-1431655766.1 AND 0xffffffff", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 AND 0xffffffff", 0xaaaaaaaau);
testUInt32Calc("0xffffffff AND -1431655766.1", 0xaaaaaaaau);
testUInt32Calc("0xffffffff AND 2863311530.1", 0xaaaaaaaau);
testUInt32Calc("~ -1431655766.1", 0x55555555u);
testUInt32Calc("~ 2863311530.1", 0x55555555u);
testUInt32Calc("-1431655766.1 >> 0", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 >> 0", 0xaaaaaaaau);
testUInt32Calc("-1431655766.1 >> 0.1", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 >> 0.1", 0xaaaaaaaau);
testUInt32Calc("-1431655766.1 << 0", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 << 0", 0xaaaaaaaau);
testUInt32Calc("-1431655766.1 << 0.1", 0xaaaaaaaau);
testUInt32Calc("2863311530.1 << 0.1", 0xaaaaaaaau);
return testDone();
}
+117
View File
@@ -0,0 +1,117 @@
/*************************************************************************\
* Copyright (c) 2015 Michael Davidsaver
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <stdio.h>
#include "envDefs.h"
#include "epicsTime.h"
#include "epicsUnitTest.h"
#include "testMain.h"
#if defined(_WIN32)
# define tzset _tzset
#endif
static
void setTZ(const char *base, const char *dst, int offset)
{
char tz[20];
if(offset!=0 || dst)
sprintf(tz, "%s%d%s", base, offset/3600, dst);
else
sprintf(tz, "%s", base);
testDiag("TZ=\"%s\"", tz);
epicsEnvSet("TZ", tz);
tzset();
}
static
void test_localtime(time_t T, int sec, int min, int hour,
int mday, int mon, int year,
int wday, int yday, int isdst)
{
struct tm B;
testDiag("test_localtime(%ld, ...)", (long)T);
if(epicsTime_localtime(&T, &B)!=epicsTimeOK) {
testFail("epicsTime_localtime() error");
testSkip(9, "epicsTime_localtime() failed");
} else {
B.tm_year += 1900; /* for readability */
testPass("epicsTime_localtime() success");
#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD)
TEST(sec);
TEST(min);
TEST(hour);
TEST(mday);
TEST(mon);
TEST(year);
TEST(wday);
TEST(yday);
TEST(isdst);
#undef TEST
}
}
static
void test_gmtime(time_t T, int sec, int min, int hour,
int mday, int mon, int year,
int wday, int yday, int isdst)
{
struct tm B;
testDiag("test_gmtime(%ld, ...)", (long)T);
if(epicsTime_gmtime(&T, &B)!=epicsTimeOK) {
testFail("epicsTime_localtime() error");
testSkip(9, "epicsTime_localtime() failed");
} else {
B.tm_year += 1900; /* for readability */
testPass("epicsTime_localtime() success");
#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD)
TEST(sec);
TEST(min);
TEST(hour);
TEST(mday);
TEST(mon);
TEST(year);
TEST(wday);
TEST(yday);
TEST(isdst);
#undef TEST
}
}
MAIN(epicsTimeZoneTest)
{
testPlan(80);
/* 1445259616
* Mon Oct 19 09:00:16 2015 EDT
* Mon Oct 19 08:00:16 2015 CDT
* Mon Oct 19 13:00:16 2015 UTC
*/
testDiag("POSIX 1445259616");
setTZ("EST", "EDT", 5*3600);
test_localtime(1445259616ul, 16, 0, 9, 19, 9, 2015, 1, 291, 1);
setTZ("CST", "CDT", 6*3600);
test_localtime(1445259616ul, 16, 0, 8, 19, 9, 2015, 1, 291, 1);
setTZ("UTC", NULL, 0);
test_localtime(1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0);
test_gmtime(1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0);
/* 1421244931
* Wed Jan 14 09:15:31 2015 EST
* Wed Jan 14 08:15:31 2015 CST
* Wed Jan 14 14:15:31 2015 UTC
*/
testDiag("POSIX 1421244931");
setTZ("EST", "EDT", 5*3600);
test_localtime(1421244931ul, 31, 15, 9, 14, 0, 2015, 3, 13, 0);
setTZ("CST", "CDT", 6*3600);
test_localtime(1421244931ul, 31, 15, 8, 14, 0, 2015, 3, 13, 0);
setTZ("UTC", NULL, 0);
test_localtime(1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0);
test_gmtime(1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0);
return testDone();
}
+1 -1
View File
@@ -17,5 +17,5 @@ softMain$(DEP): epicsInstallDir.h
epicsInstallDir.h:
$(ECHO) "FINAL_LOCATION=$(FINAL_LOCATION)"
$(PERL) $(STDDIR)/softIoc/makeInstallDir.pl '$(FINAL_LOCATION)' > $@
$(PERL) $(STDDIR)/softIoc/makeInstallDir.pl "$(FINAL_LOCATION)" > $@
+2 -1
View File
@@ -9,7 +9,8 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
use strict;
die "Path to INSTALL_LOCATION missing\n" unless @ARGV == 1;
die "$0: Argument missing, INSTALL_LOCATION\n" if @ARGV == 0;
die "$0: Too many arguments, expecting one\n" unless @ARGV == 1;
my $path = shift;
+22 -27
View File
@@ -1,48 +1,43 @@
# $Revision-Id$
# CONFIG - Load build configuration data
#
# Do not make changes in this file, any site-specific
# overrides should be given in a CONFIG_SITE file.
# You might want to change this to some shared set of rules, e.g.
# RULES=/path/to/epics/support/modules/rules/x-y
RULES=$(EPICS_BASE)
# Where the build rules come from
RULES = $(EPICS_BASE)
INSTALL_IDLFILE = $(INSTALL)
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG=$(RULES)/configure
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override for definition in base
# Override some Base definitions
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain build configuration overrides
include $(TOP)/configure/CONFIG_SITE
ifdef INSTALL_LOCATION_EXTENSIONS
INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS)
endif
# Site specific host architecture definitions
# Host-arch specific settings
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef INSTALL_LOCATION_EXTENSIONS
INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS)
endif
ifdef T_A
# Target-arch specific settings
-include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A)
# Site specific target architecture definitions
-include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A)
# Cross compile specific definitions
ifneq ($(EPICS_HOST_ARCH),$(T_A))
-include $(TOP)/configure/CONFIG.CrossCommon
endif
# Site specific host-target combination definitions
-include $(TOP)/configure/os/CONFIG.$(EPICS_HOST_ARCH).$(T_A)
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
-include $(TOP)/configure/O.$(T_A)/CONFIG_APP_INCLUDE
# Host & target specific combination settings
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
+12 -11
View File
@@ -1,22 +1,23 @@
#RELEASE Location of external products
# RELEASE Locations of external modules
#
# NOTE: The build does not check dependancies on files
# external to this application. Thus you should run
# "gnumake clean uninstall install" in the top directory
# each time EPICS_BASE, SNCSEQ, or any other external
# module defined in a RELEASE* file is rebuilt.
# each time EPICS_BASE or any other external module that
# is defined in a RELEASE* file gets rebuilt.
#
# Host/target specific settings can be specified in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# Host/target specific paths can be specified in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# Define INSTALL_LOCATION in CONFIG_SITE
# Location of external products
EPICS_BASE=_EPICS_BASE_
EPICS_EXTENSIONS = $(TOP)
# OAG_APPS may be needed by extension SDDS
#OAG_APPS=$(TOP)/../../oag/apps
# Locations of external modules
# OAG_APPS may be needed by the SDDS extension
#OAG_APPS = $(TOP)/../../oag/apps
EPICS_BASE = _EPICS_BASE_
+4 -3
View File
@@ -1,8 +1,9 @@
# $Revision-Id$
include $(CONFIG)/RULES
include $(TOP)/configure/RULES_PYTHON
include $(TOP)/configure/RULES_IDL
-include $(TOP)/configure/RULES_PYTHON
-include $(TOP)/configure/RULES_IDL
ifdef BASE_3_15
include $(TOP)/configure/RULES_JAVA
-include $(TOP)/configure/RULES_JAVA
endif
@@ -43,7 +43,11 @@ $(PYTHON_PACKAGE_PTH):
%_wrap.c: ../%.i
$(SWIG) -python -o $@ $<
ifdef BASE_3_15
clean:
else
clean::
endif
@$(RM) *.py *.so *.pth
endif