Merge 7.0 into rtems5
This commit is contained in:
@ -71,6 +71,8 @@ INSTALL_DBD = $(INSTALL_LOCATION)/dbd
|
|||||||
INSTALL_DB = $(INSTALL_LOCATION)/db
|
INSTALL_DB = $(INSTALL_LOCATION)/db
|
||||||
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
|
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
|
||||||
|
|
||||||
|
FINAL_LOCATION = $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
||||||
|
|
||||||
# Directory for OS independant build created files
|
# Directory for OS independant build created files
|
||||||
COMMON_DIR = ../O.Common
|
COMMON_DIR = ../O.Common
|
||||||
|
|
||||||
|
@ -155,6 +155,14 @@ CROSS_WARN=YES
|
|||||||
# different location then uncomment and set this.
|
# different location then uncomment and set this.
|
||||||
#INSTALL_LOCATION=<fullpathname>
|
#INSTALL_LOCATION=<fullpathname>
|
||||||
|
|
||||||
|
# The location from which files placed in INSTALL_LOCATION will actually run.
|
||||||
|
# This path is compiled into executables, and so should be an absolute.
|
||||||
|
# May be used to achieve the effect of autotools. eg.
|
||||||
|
# ./configure --prefix=<FINAL_LOCATION>
|
||||||
|
# make DESTDIR=<INSTALL_LOCATION>
|
||||||
|
# Defaults to the absolute expansion of $(INSTALL_LOCATION)
|
||||||
|
#FINAL_LOCATION=
|
||||||
|
|
||||||
# Use POSIX thread priority scheduling (if available).
|
# Use POSIX thread priority scheduling (if available).
|
||||||
# Must be either YES or NO
|
# Must be either YES or NO
|
||||||
USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
||||||
|
@ -17,6 +17,61 @@ should also be read to understand what has changed since earlier releases.
|
|||||||
|
|
||||||
<!-- Insert new items immediately below here ... -->
|
<!-- Insert new items immediately below here ... -->
|
||||||
|
|
||||||
|
### epicsEnvShow accepts glob pattern
|
||||||
|
|
||||||
|
The optional argument to epicsEnvShow can now be a glob pattern.
|
||||||
|
|
||||||
|
### New function `epicsStrnGlobMatch()`
|
||||||
|
|
||||||
|
The function `epicsStrnGlobMatch(char* str, size_t len, char* pattern)`
|
||||||
|
works exactly the same as `epicsStrGlobMatch()` but takes an additional
|
||||||
|
length arguments which limits the number of characters of `str` to match.
|
||||||
|
|
||||||
|
### Automatic fallback to thread when unable to exec caRepeater
|
||||||
|
|
||||||
|
A process using libca which does not find an existing caRepeater process
|
||||||
|
will attempt to start one by running the caRepeater executable.
|
||||||
|
This is not always possible, usually when caRepeater is not in `$PATH`.
|
||||||
|
Now, instead of printing a warning, an internal caRepeater thread
|
||||||
|
will be started (as is done be RTEMS and vxWorks targets).
|
||||||
|
|
||||||
|
If this fallback occurs, the lifetime of the caRepeater thread
|
||||||
|
may be shorter than the lifetime of a separate caRepeater process
|
||||||
|
would have been.
|
||||||
|
|
||||||
|
It remains the recommended practice to explicitly start a caRepeater
|
||||||
|
instance. Examples of both systemd (`caRepeater.service`) and sysv
|
||||||
|
(`S99caRepeater`) scripts may be found under `bin/`.
|
||||||
|
|
||||||
|
### Glob pattern allowed in `var` command
|
||||||
|
|
||||||
|
When used with one argument, the `var` command can be used with a glob pattern
|
||||||
|
for printing matching variables.
|
||||||
|
|
||||||
|
### Formalize/fix `FINAL_LOCATION`
|
||||||
|
|
||||||
|
The `FINAL_LOCATION` make variable has for some time been an undocumented
|
||||||
|
means of performing a staged build. This is a build which "installs" to
|
||||||
|
a temporary location, which will later be moved to a final location.
|
||||||
|
|
||||||
|
This has now been added to `configure/CONFIG_SITE`.
|
||||||
|
|
||||||
|
Usage analogous to the autotools recipe
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./configure --prefix=/usr/lib/epics
|
||||||
|
make install DESTDIR=/tmp/build
|
||||||
|
```
|
||||||
|
|
||||||
|
would be
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make INSTALL_LOCATION=/tmp/build FINAL_LOCATION=/usr/lib/epics
|
||||||
|
```
|
||||||
|
|
||||||
|
`FINAL_LOCATION` is now correctly used in systemd and sysv init scripts
|
||||||
|
`caRepeater.service`, `S99caRepeater`, and `S99logServer`.
|
||||||
|
|
||||||
### IOCsh sets `${PWD}`
|
### IOCsh sets `${PWD}`
|
||||||
|
|
||||||
IOC shell will now ensure `${PWD}` is set on startup,
|
IOC shell will now ensure `${PWD}` is set on startup,
|
||||||
|
@ -113,7 +113,7 @@ SCRIPTS_Linux = caRepeater.service
|
|||||||
|
|
||||||
EXPAND += S99caRepeater@
|
EXPAND += S99caRepeater@
|
||||||
EXPAND += caRepeater.service@
|
EXPAND += caRepeater.service@
|
||||||
EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN))
|
EXPAND_VARS = INSTALL_BIN=$(FINAL_LOCATION)/bin/$(T_A)
|
||||||
|
|
||||||
SRC_DIRS += $(CURDIR)/test
|
SRC_DIRS += $(CURDIR)/test
|
||||||
PROD_HOST += ca_test
|
PROD_HOST += ca_test
|
||||||
|
@ -629,8 +629,8 @@ void epicsStdCall caStartRepeaterIfNotInstalled ( unsigned repeaterPort )
|
|||||||
* repeater's port)
|
* repeater's port)
|
||||||
*/
|
*/
|
||||||
osiSpawnDetachedProcessReturn osptr =
|
osiSpawnDetachedProcessReturn osptr =
|
||||||
osiSpawnDetachedProcess ( "CA Repeater", "caRepeater" );
|
osiSpawnDetachedProcess ( "!CA Repeater", "caRepeater" );
|
||||||
if ( osptr == osiSpawnDetachedProcessNoSupport ) {
|
if ( osptr != osiSpawnDetachedProcessSuccess ) {
|
||||||
epicsThreadId tid;
|
epicsThreadId tid;
|
||||||
|
|
||||||
tid = epicsThreadCreate ( "CAC-repeater", epicsThreadPriorityLow,
|
tid = epicsThreadCreate ( "CAC-repeater", epicsThreadPriorityLow,
|
||||||
@ -639,9 +639,6 @@ void epicsStdCall caStartRepeaterIfNotInstalled ( unsigned repeaterPort )
|
|||||||
fprintf ( stderr, "caStartRepeaterIfNotInstalled : unable to create CA repeater daemon thread\n" );
|
fprintf ( stderr, "caStartRepeaterIfNotInstalled : unable to create CA repeater daemon thread\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( osptr == osiSpawnDetachedProcessFail ) {
|
|
||||||
fprintf ( stderr, "caStartRepeaterIfNotInstalled (): unable to start CA repeater daemon detached process\n" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,5 @@ softIoc_LIBS = $(EPICS_BASE_IOC_LIBS)
|
|||||||
|
|
||||||
DB += softIocExit.db
|
DB += softIocExit.db
|
||||||
|
|
||||||
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
|
||||||
|
|
||||||
CLEANS += epicsInstallDir.h
|
CLEANS += epicsInstallDir.h
|
||||||
|
|
||||||
|
@ -249,7 +249,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (loadedDb || ranScript) {
|
if (loadedDb || ranScript) {
|
||||||
epicsThreadExitMain();
|
// non-interactive IOC. spin forever
|
||||||
|
while(true) {
|
||||||
|
epicsThreadSleep(1000.0);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
usage(argv[0], dbd_file);
|
usage(argv[0], dbd_file);
|
||||||
|
@ -40,7 +40,6 @@ HTMLS += dbdToHtml.html
|
|||||||
|
|
||||||
# Build Package Config Files
|
# Build Package Config Files
|
||||||
|
|
||||||
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
|
||||||
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CPPFLAGS))))
|
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CPPFLAGS))))
|
||||||
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CFLAGS))))
|
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CFLAGS))))
|
||||||
PKGVARS += FINAL_LOCATION OS_CLASS CMPLR_CLASS C_CFLAGS LDFLAGS LDLIBS
|
PKGVARS += FINAL_LOCATION OS_CLASS CMPLR_CLASS C_CFLAGS LDFLAGS LDLIBS
|
||||||
|
@ -12,9 +12,11 @@
|
|||||||
#include <testMain.h>
|
#include <testMain.h>
|
||||||
#include <dbAccess.h>
|
#include <dbAccess.h>
|
||||||
#include <epicsTime.h>
|
#include <epicsTime.h>
|
||||||
|
#include <epicsEvent.h>
|
||||||
#include <epicsThread.h>
|
#include <epicsThread.h>
|
||||||
#include <errlog.h>
|
#include <errlog.h>
|
||||||
#include <alarm.h>
|
#include <alarm.h>
|
||||||
|
#include <callback.h>
|
||||||
|
|
||||||
#include "recSup.h"
|
#include "recSup.h"
|
||||||
#include "aiRecord.h"
|
#include "aiRecord.h"
|
||||||
@ -414,6 +416,15 @@ void testSiolWrite(const char *name,
|
|||||||
* Asynchronous processing using simm:DELAY
|
* Asynchronous processing using simm:DELAY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
ping(CALLBACK *pcb)
|
||||||
|
{
|
||||||
|
epicsEventId ev;
|
||||||
|
callbackGetUser(ev, pcb);
|
||||||
|
|
||||||
|
epicsEventMustTrigger(ev);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void testSimmDelay(const char *name,
|
void testSimmDelay(const char *name,
|
||||||
epicsFloat64 *psdly,
|
epicsFloat64 *psdly,
|
||||||
@ -422,6 +433,14 @@ void testSimmDelay(const char *name,
|
|||||||
epicsTimeStamp now;
|
epicsTimeStamp now;
|
||||||
const double delay = 0.01; /* 10 ms */
|
const double delay = 0.01; /* 10 ms */
|
||||||
double diff;
|
double diff;
|
||||||
|
epicsEventId poked;
|
||||||
|
CALLBACK cb;
|
||||||
|
|
||||||
|
memset(&cb, 0, sizeof(CALLBACK));
|
||||||
|
poked = epicsEventMustCreate(epicsEventEmpty);
|
||||||
|
callbackSetCallback(ping, &cb);
|
||||||
|
callbackSetPriority(priorityLow, &cb);
|
||||||
|
callbackSetUser(poked, &cb);
|
||||||
|
|
||||||
testDiag("## Asynchronous processing with simm:DELAY ##");
|
testDiag("## Asynchronous processing with simm:DELAY ##");
|
||||||
|
|
||||||
@ -443,14 +462,11 @@ void testSimmDelay(const char *name,
|
|||||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 1);
|
testdbGetFieldEqual(namePACT, DBR_USHORT, 1);
|
||||||
epicsTimeGetCurrent(&now);
|
epicsTimeGetCurrent(&now);
|
||||||
epicsThreadSleep(1.75*delay);
|
callbackRequestDelayed(&cb, 1.5 * delay);
|
||||||
if(testImpreciseTiming())
|
epicsEventWait(poked);
|
||||||
testTodoBegin("imprecise");
|
|
||||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
||||||
diff = epicsTimeDiffInSeconds(mytime, &now);
|
diff = epicsTimeDiffInSeconds(mytime, &now);
|
||||||
testOk(diff >= 0.0, "time stamp is recent (%.9f sec)", diff);
|
testOk(diff >= 0.0, "time stamp is recent (%.9f sec)", diff);
|
||||||
if(testImpreciseTiming())
|
|
||||||
testTodoEnd();
|
|
||||||
|
|
||||||
/* Reset delay */
|
/* Reset delay */
|
||||||
*psdly = -1.;
|
*psdly = -1.;
|
||||||
|
@ -1126,17 +1126,26 @@ static void varHandler(const iocshVarDef *v, const char *setString)
|
|||||||
static void varCallFunc(const iocshArgBuf *args)
|
static void varCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
struct iocshVariable *v;
|
struct iocshVariable *v;
|
||||||
if(args[0].sval == NULL) {
|
const char *name = args[0].sval;
|
||||||
|
const char *value = args[1].sval;
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
int found = 0;
|
||||||
for (v = iocshVariableHead ; v != NULL ; v = v->next)
|
for (v = iocshVariableHead ; v != NULL ; v = v->next)
|
||||||
varHandler(v->pVarDef, args[1].sval);
|
if (!name || epicsStrGlobMatch(v->pVarDef->name, name) != 0) {
|
||||||
|
varHandler(v->pVarDef, NULL);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
if (!found && name != NULL)
|
||||||
|
fprintf(epicsGetStderr(), "No var matching %s found.\n", name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v = (iocshVariable *)registryFind(iocshVarID, args[0].sval);
|
v = (iocshVariable *)registryFind(iocshVarID, args[0].sval);
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval);
|
fprintf(epicsGetStderr(), "Var %s not found.\n", name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
varHandler(v->pVarDef, args[1].sval);
|
varHandler(v->pVarDef, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,5 @@ iocLogServer_SYS_LIBS_WIN32 += user32 ws2_32 dbghelp
|
|||||||
SCRIPTS_HOST = S99logServer
|
SCRIPTS_HOST = S99logServer
|
||||||
|
|
||||||
EXPAND += S99logServer@
|
EXPAND += S99logServer@
|
||||||
EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN))
|
EXPAND_VARS = INSTALL_BIN=$(FINAL_LOCATION)/bin/$(T_A)
|
||||||
|
|
||||||
|
@ -23,6 +23,15 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifndef vxWorks
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
/* VxWorks automaticaly includes stdint.h defining SIZE_MAX in 6.9 but not earlier */
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
#define SIZE_MAX (size_t)-1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "epicsAssert.h"
|
#include "epicsAssert.h"
|
||||||
#include "epicsStdio.h"
|
#include "epicsStdio.h"
|
||||||
#include "cantProceed.h"
|
#include "cantProceed.h"
|
||||||
@ -259,30 +268,31 @@ size_t epicsStrnLen(const char *s, size_t maxlen)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int epicsStrGlobMatch(const char *str, const char *pattern)
|
int epicsStrnGlobMatch(const char *str, size_t len, const char *pattern)
|
||||||
{
|
{
|
||||||
const char *cp = NULL, *mp = NULL;
|
const char *mp = NULL;
|
||||||
|
size_t cp = 0, i = 0;
|
||||||
|
|
||||||
while ((*str) && (*pattern != '*')) {
|
while ((i < len) && (str[i]) && (*pattern != '*')) {
|
||||||
if ((*pattern != *str) && (*pattern != '?'))
|
if ((*pattern != str[i]) && (*pattern != '?'))
|
||||||
return 0;
|
return 0;
|
||||||
pattern++;
|
pattern++;
|
||||||
str++;
|
i++;
|
||||||
}
|
}
|
||||||
while (*str) {
|
while ((i < len) && str[i]) {
|
||||||
if (*pattern == '*') {
|
if (*pattern == '*') {
|
||||||
if (!*++pattern)
|
if (!*++pattern)
|
||||||
return 1;
|
return 1;
|
||||||
mp = pattern;
|
mp = pattern;
|
||||||
cp = str+1;
|
cp = i+1;
|
||||||
}
|
}
|
||||||
else if ((*pattern == *str) || (*pattern == '?')) {
|
else if ((*pattern == str[i]) || (*pattern == '?')) {
|
||||||
pattern++;
|
pattern++;
|
||||||
str++;
|
i++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pattern = mp;
|
pattern = mp;
|
||||||
str = cp++;
|
i = cp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (*pattern == '*')
|
while (*pattern == '*')
|
||||||
@ -290,6 +300,10 @@ int epicsStrGlobMatch(const char *str, const char *pattern)
|
|||||||
return !*pattern;
|
return !*pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int epicsStrGlobMatch(const char *str, const char *pattern) {
|
||||||
|
return epicsStrnGlobMatch(str, SIZE_MAX, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
char * epicsStrtok_r(char *s, const char *delim, char **lasts)
|
char * epicsStrtok_r(char *s, const char *delim, char **lasts)
|
||||||
{
|
{
|
||||||
const char *spanp;
|
const char *spanp;
|
||||||
|
@ -36,7 +36,30 @@ LIBCOM_API char * epicsStrnDup(const char *s, size_t len);
|
|||||||
LIBCOM_API int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n);
|
LIBCOM_API int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n);
|
||||||
#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw
|
#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw
|
||||||
LIBCOM_API size_t epicsStrnLen(const char *s, size_t maxlen);
|
LIBCOM_API size_t epicsStrnLen(const char *s, size_t maxlen);
|
||||||
|
|
||||||
|
/** Matches a string against a pattern.
|
||||||
|
*
|
||||||
|
* Checks if str matches the glob style pattern, which may contain ? or * wildcards.
|
||||||
|
* A ? matches any single character.
|
||||||
|
* A * matched any sub-string.
|
||||||
|
*
|
||||||
|
* @returns 1 if str matches the pattern, 0 if not.
|
||||||
|
*
|
||||||
|
* @since EPICS 3.14.7
|
||||||
|
*/
|
||||||
LIBCOM_API int epicsStrGlobMatch(const char *str, const char *pattern);
|
LIBCOM_API int epicsStrGlobMatch(const char *str, const char *pattern);
|
||||||
|
|
||||||
|
/** Matches a string against a pattern.
|
||||||
|
*
|
||||||
|
* Like epicsStrGlobMatch but with limited string length.
|
||||||
|
* If the length of str is less than len, the full string is matched.
|
||||||
|
*
|
||||||
|
* @returns 1 if the first len characters of str match the pattern, 0 if not.
|
||||||
|
*
|
||||||
|
* @since UNRELEASED
|
||||||
|
*/
|
||||||
|
LIBCOM_API int epicsStrnGlobMatch(const char *str, size_t len, const char *pattern);
|
||||||
|
|
||||||
LIBCOM_API char * epicsStrtok_r(char *s, const char *delim, char **lasts);
|
LIBCOM_API char * epicsStrtok_r(char *s, const char *delim, char **lasts);
|
||||||
LIBCOM_API unsigned int epicsStrHash(const char *str, unsigned int seed);
|
LIBCOM_API unsigned int epicsStrHash(const char *str, unsigned int seed);
|
||||||
LIBCOM_API unsigned int epicsMemHash(const char *str, size_t length,
|
LIBCOM_API unsigned int epicsMemHash(const char *str, size_t length,
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "libComAPI.h"
|
#include "libComAPI.h"
|
||||||
|
#include "compilerDependencies.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -142,8 +143,12 @@ LIBCOM_API void epicsThreadRealtimeLock(void);
|
|||||||
* call this routine. This should be the last call in main, except the
|
* call this routine. This should be the last call in main, except the
|
||||||
* final return. On most systems epicsThreadExitMain never returns.This
|
* final return. On most systems epicsThreadExitMain never returns.This
|
||||||
* must only be called by the main thread.
|
* must only be called by the main thread.
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated for lack of use. Please report any usage.
|
||||||
|
* Recommended replacement is loop + epicsThreadSleep(),
|
||||||
|
* epicsEventMustWait(), or similar.
|
||||||
**/
|
**/
|
||||||
LIBCOM_API void epicsStdCall epicsThreadExitMain(void);
|
LIBCOM_API void epicsStdCall epicsThreadExitMain(void) EPICS_DEPRECATED;
|
||||||
|
|
||||||
/** For use with epicsThreadCreateOpt() */
|
/** For use with epicsThreadCreateOpt() */
|
||||||
typedef struct epicsThreadOpts {
|
typedef struct epicsThreadOpts {
|
||||||
|
@ -219,6 +219,8 @@ threadWrapper (rtems_task_argument arg)
|
|||||||
*/
|
*/
|
||||||
void epicsThreadExitMain (void)
|
void epicsThreadExitMain (void)
|
||||||
{
|
{
|
||||||
|
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
|
||||||
|
" Please report if you see this message.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code
|
static rtems_status_code
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "epicsStdio.h"
|
#include "epicsStdio.h"
|
||||||
|
#include "epicsString.h"
|
||||||
#include "errlog.h"
|
#include "errlog.h"
|
||||||
#include "envDefs.h"
|
#include "envDefs.h"
|
||||||
#include "osiUnistd.h"
|
#include "osiUnistd.h"
|
||||||
@ -61,18 +61,10 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
|||||||
*/
|
*/
|
||||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||||
{
|
{
|
||||||
if (name == NULL) {
|
char **sp;
|
||||||
extern char **environ;
|
|
||||||
char **sp;
|
|
||||||
|
|
||||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
|
||||||
|
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
|
||||||
printf ("%s\n", *sp);
|
printf ("%s\n", *sp);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
const char *cp = getenv (name);
|
|
||||||
if (cp == NULL)
|
|
||||||
printf ("%s is not an environment variable.\n", name);
|
|
||||||
else
|
|
||||||
printf ("%s=%s\n", name, cp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -92,17 +92,27 @@ LIBCOM_API epicsEventStatus epicsEventWait ( epicsEventId pSem )
|
|||||||
LIBCOM_API epicsEventStatus epicsEventWaitWithTimeout (
|
LIBCOM_API epicsEventStatus epicsEventWaitWithTimeout (
|
||||||
epicsEventId pSem, double timeOut )
|
epicsEventId pSem, double timeOut )
|
||||||
{
|
{
|
||||||
static const unsigned nSec100PerSec = 10000000u;
|
/* waitable timers use 100 nanosecond intervals, like FILETIME */
|
||||||
|
static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */
|
||||||
|
static const unsigned mSecPerSec = 1000u; /* milliseconds per second */
|
||||||
HANDLE handles[2];
|
HANDLE handles[2];
|
||||||
DWORD status;
|
DWORD status;
|
||||||
LARGE_INTEGER tmo;
|
LARGE_INTEGER tmo;
|
||||||
HANDLE timer;
|
HANDLE timer;
|
||||||
|
LONGLONG nIvals; /* number of intervals */
|
||||||
|
|
||||||
if ( timeOut <= 0.0 ) {
|
if ( timeOut <= 0.0 ) {
|
||||||
tmo.QuadPart = 0u;
|
tmo.QuadPart = 0u;
|
||||||
}
|
}
|
||||||
|
else if ( timeOut >= INFINITE / mSecPerSec ) {
|
||||||
|
/* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds,
|
||||||
|
to be compatible with previous WaitForSingleObject() implementation */
|
||||||
|
nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec);
|
||||||
|
tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
tmo.QuadPart = -((LONGLONG)(timeOut * nSec100PerSec + 0.5));
|
nIvals = (LONGLONG)(timeOut * ivalPerSec + 0.999999);
|
||||||
|
tmo.QuadPart = -nIvals;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmo.QuadPart < 0) {
|
if (tmo.QuadPart < 0) {
|
||||||
|
@ -50,10 +50,14 @@ LIBCOM_API osiGetUserNameReturn epicsStdCall osiGetUserName (char *pBuf, unsigne
|
|||||||
LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
||||||
( const char *pProcessName, const char *pBaseExecutableName )
|
( const char *pProcessName, const char *pBaseExecutableName )
|
||||||
{
|
{
|
||||||
|
BOOL silent = pProcessName && pProcessName[0]=='!';
|
||||||
BOOL status;
|
BOOL status;
|
||||||
STARTUPINFO startupInfo;
|
STARTUPINFO startupInfo;
|
||||||
PROCESS_INFORMATION processInfo;
|
PROCESS_INFORMATION processInfo;
|
||||||
|
|
||||||
|
if(silent)
|
||||||
|
pProcessName++; /* skip '!' */
|
||||||
|
|
||||||
GetStartupInfo ( &startupInfo );
|
GetStartupInfo ( &startupInfo );
|
||||||
startupInfo.lpReserved = NULL;
|
startupInfo.lpReserved = NULL;
|
||||||
startupInfo.lpTitle = (char *) pProcessName;
|
startupInfo.lpTitle = (char *) pProcessName;
|
||||||
@ -115,7 +119,7 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
|||||||
/* Free the buffer. */
|
/* Free the buffer. */
|
||||||
LocalFree (errStrMsgBuf);
|
LocalFree (errStrMsgBuf);
|
||||||
}
|
}
|
||||||
else {
|
else if(!silent) {
|
||||||
fprintf (stderr, "!!WARNING!!\n");
|
fprintf (stderr, "!!WARNING!!\n");
|
||||||
fprintf (stderr, "Unable to locate executable \"%s\".\n", pBaseExecutableName);
|
fprintf (stderr, "Unable to locate executable \"%s\".\n", pBaseExecutableName);
|
||||||
fprintf (stderr, "You may need to modify your \"path\" environment variable.\n");
|
fprintf (stderr, "You may need to modify your \"path\" environment variable.\n");
|
||||||
|
@ -260,7 +260,8 @@ static void epicsParmCleanupWIN32 ( win32ThreadParam * pParm )
|
|||||||
*/
|
*/
|
||||||
LIBCOM_API void epicsStdCall epicsThreadExitMain ( void )
|
LIBCOM_API void epicsStdCall epicsThreadExitMain ( void )
|
||||||
{
|
{
|
||||||
_endthread ();
|
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
|
||||||
|
" Please report if you see this message.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -818,15 +819,25 @@ HANDLE osdThreadGetTimer()
|
|||||||
*/
|
*/
|
||||||
LIBCOM_API void epicsStdCall epicsThreadSleep ( double seconds )
|
LIBCOM_API void epicsStdCall epicsThreadSleep ( double seconds )
|
||||||
{
|
{
|
||||||
static const unsigned nSec100PerSec = 10000000u;
|
/* waitable timers use 100 nanosecond intervals, like FILETIME */
|
||||||
|
static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */
|
||||||
|
static const unsigned mSecPerSec = 1000u; /* milliseconds per second */
|
||||||
LARGE_INTEGER tmo;
|
LARGE_INTEGER tmo;
|
||||||
HANDLE timer;
|
HANDLE timer;
|
||||||
|
LONGLONG nIvals; /* number of intervals */
|
||||||
|
|
||||||
if ( seconds <= 0.0 ) {
|
if ( seconds <= 0.0 ) {
|
||||||
tmo.QuadPart = 0u;
|
tmo.QuadPart = 0u;
|
||||||
}
|
}
|
||||||
|
else if ( seconds >= INFINITE / mSecPerSec ) {
|
||||||
|
/* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds,
|
||||||
|
to be compatible with previous WaitForSingleObject() implementation */
|
||||||
|
nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec);
|
||||||
|
tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
tmo.QuadPart = -((LONGLONG)(seconds * nSec100PerSec + 0.5));
|
nIvals = (LONGLONG)(seconds * ivalPerSec + 0.999999);
|
||||||
|
tmo.QuadPart = -nIvals;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmo.QuadPart == 0) {
|
if (tmo.QuadPart == 0) {
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "epicsStdio.h"
|
#include "epicsStdio.h"
|
||||||
|
#include "epicsString.h"
|
||||||
#include "epicsVersion.h"
|
#include "epicsVersion.h"
|
||||||
#include "errlog.h"
|
#include "errlog.h"
|
||||||
#include "envDefs.h"
|
#include "envDefs.h"
|
||||||
@ -68,18 +68,11 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
|||||||
*/
|
*/
|
||||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||||
{
|
{
|
||||||
if (name == NULL) {
|
extern char **environ;
|
||||||
extern char **environ;
|
char **sp;
|
||||||
char **sp;
|
|
||||||
|
|
||||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
|
||||||
|
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
|
||||||
printf ("%s\n", *sp);
|
printf ("%s\n", *sp);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
const char *cp = getenv (name);
|
|
||||||
if (cp == NULL)
|
|
||||||
printf ("%s is not an environment variable.\n", name);
|
|
||||||
else
|
|
||||||
printf ("%s=%s\n", name, cp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "osiProcess.h"
|
#include "osiProcess.h"
|
||||||
#include "errlog.h"
|
#include "errlog.h"
|
||||||
@ -61,12 +63,22 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
|||||||
(const char *pProcessName, const char *pBaseExecutableName)
|
(const char *pProcessName, const char *pBaseExecutableName)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
int silent = pProcessName && pProcessName[0]=='!';
|
||||||
|
int fds[2]; /* [reader, writer] */
|
||||||
|
|
||||||
|
if(silent)
|
||||||
|
pProcessName++; /* skip '!' */
|
||||||
|
|
||||||
|
if(pipe(fds))
|
||||||
|
return osiSpawnDetachedProcessFail;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a duplicate process
|
* create a duplicate process
|
||||||
*/
|
*/
|
||||||
status = fork ();
|
status = fork ();
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
|
close(fds[0]);
|
||||||
|
close(fds[1]);
|
||||||
return osiSpawnDetachedProcessFail;
|
return osiSpawnDetachedProcessFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,11 +87,29 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
|||||||
* in the initiating (parent) process
|
* in the initiating (parent) process
|
||||||
*/
|
*/
|
||||||
if (status) {
|
if (status) {
|
||||||
return osiSpawnDetachedProcessSuccess;
|
osiSpawnDetachedProcessReturn ret = osiSpawnDetachedProcessSuccess;
|
||||||
}
|
char buf;
|
||||||
|
ssize_t n;
|
||||||
|
close(fds[1]);
|
||||||
|
|
||||||
/*
|
n = read(fds[0], &buf, 1);
|
||||||
* This is executed only by the new child process.
|
/* Success if child exec'd without sending a '!'.
|
||||||
|
* Of course child may crash soon after, but can't
|
||||||
|
* wait around for this to happen.
|
||||||
|
*/
|
||||||
|
if(n!=0) {
|
||||||
|
ret = osiSpawnDetachedProcessFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fds[0]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
close(fds[0]);
|
||||||
|
(void)fcntl ( fds[1], F_SETFD, FD_CLOEXEC );
|
||||||
|
|
||||||
|
/* This is executed only by the new child process.
|
||||||
|
* Since we may be called from a library, we don't assume that
|
||||||
|
* all other code has set properly set FD_CLOEXEC.
|
||||||
* Close all open files except for STDIO, so they will not
|
* Close all open files except for STDIO, so they will not
|
||||||
* be inherited by the new program.
|
* be inherited by the new program.
|
||||||
*/
|
*/
|
||||||
@ -89,6 +119,8 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
|||||||
if (fd==STDIN_FILENO) continue;
|
if (fd==STDIN_FILENO) continue;
|
||||||
if (fd==STDOUT_FILENO) continue;
|
if (fd==STDOUT_FILENO) continue;
|
||||||
if (fd==STDERR_FILENO) continue;
|
if (fd==STDERR_FILENO) continue;
|
||||||
|
/* pipe to our parent will be closed automatically via FD_CLOEXEC */
|
||||||
|
if (fd==fds[1]) continue;
|
||||||
close (fd);
|
close (fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,12 +141,16 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
|
|||||||
* Run the specified executable
|
* Run the specified executable
|
||||||
*/
|
*/
|
||||||
status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL);
|
status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 && !silent ) {
|
||||||
fprintf ( stderr, "**** The executable \"%s\" couldn't be located\n", pBaseExecutableName );
|
fprintf ( stderr, "**** The executable \"%s\" couldn't be located\n", pBaseExecutableName );
|
||||||
fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror (errno) );
|
fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror (errno) );
|
||||||
fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" );
|
fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" );
|
||||||
fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName);
|
fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName);
|
||||||
}
|
}
|
||||||
|
/* signal error to parent */
|
||||||
|
ssize_t ret = write(fds[1], "!", 1);
|
||||||
|
(void)ret; /* not much we could do about this */
|
||||||
|
close(fds[1]);
|
||||||
/* Don't run our parent's atexit() handlers */
|
/* Don't run our parent's atexit() handlers */
|
||||||
_exit ( -1 );
|
_exit ( -1 );
|
||||||
}
|
}
|
||||||
|
@ -690,6 +690,10 @@ LIBCOM_API void epicsStdCall epicsThreadExitMain(void)
|
|||||||
epicsThreadOSD *pthreadInfo;
|
epicsThreadOSD *pthreadInfo;
|
||||||
|
|
||||||
epicsThreadInit();
|
epicsThreadInit();
|
||||||
|
|
||||||
|
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
|
||||||
|
" Please report if you see this message.");
|
||||||
|
|
||||||
pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);
|
pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);
|
||||||
if(pthreadInfo==NULL)
|
if(pthreadInfo==NULL)
|
||||||
pthreadInfo = createImplicit();
|
pthreadInfo = createImplicit();
|
||||||
|
@ -16,17 +16,18 @@
|
|||||||
/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */
|
/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */
|
||||||
#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
|
#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <envLib.h>
|
#include <envLib.h>
|
||||||
|
|
||||||
#include "epicsFindSymbol.h"
|
#include "epicsFindSymbol.h"
|
||||||
#include "epicsStdio.h"
|
#include "epicsStdio.h"
|
||||||
|
#include "epicsString.h"
|
||||||
#include "errlog.h"
|
#include "errlog.h"
|
||||||
#include "iocsh.h"
|
#include "iocsh.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the value of an environment variable
|
* Set the value of an environment variable
|
||||||
* Leaks memory, but the assumption is that this routine won't be
|
* Leaks memory, but the assumption is that this routine won't be
|
||||||
@ -86,14 +87,12 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
|||||||
*/
|
*/
|
||||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||||
{
|
{
|
||||||
if (name == NULL) {
|
extern char **ppGlobalEnviron; /* Used in 'environ' macro but not declared in envLib.h */
|
||||||
envShow (0);
|
char **sp;
|
||||||
}
|
|
||||||
else {
|
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
|
||||||
const char *cp = getenv (name);
|
if (!**sp) continue; /* skip unset environment variables */
|
||||||
if (cp == NULL)
|
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
|
||||||
printf ("%s is not an environment variable.\n", name);
|
printf ("%s\n", *sp);
|
||||||
else
|
|
||||||
printf ("%s=%s\n", name, cp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,8 @@ void epicsThreadResume(epicsThreadId id)
|
|||||||
|
|
||||||
void epicsThreadExitMain(void)
|
void epicsThreadExitMain(void)
|
||||||
{
|
{
|
||||||
errlogPrintf("epicsThreadExitMain was called for vxWorks. Why?\n");
|
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
|
||||||
|
" Please report if you see this message.");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int epicsThreadGetPriority(epicsThreadId id)
|
unsigned int epicsThreadGetPriority(epicsThreadId id)
|
||||||
|
@ -73,6 +73,43 @@ void testGlob(void) {
|
|||||||
testOk1(epicsStrGlobMatch("hello","he*"));
|
testOk1(epicsStrGlobMatch("hello","he*"));
|
||||||
testOk1(epicsStrGlobMatch("hello","*lo"));
|
testOk1(epicsStrGlobMatch("hello","*lo"));
|
||||||
testOk1(epicsStrGlobMatch("hello","*"));
|
testOk1(epicsStrGlobMatch("hello","*"));
|
||||||
|
|
||||||
|
/* epicsStrnGlobMatch */
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("xyzq",3,"xyz"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyzq",3,"xyzm"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyzm",3,"xyzm"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyzm",0,"xyzm"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyzq",3,""));
|
||||||
|
testOk1(epicsStrnGlobMatch("xyz",0,""));
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("xyz",0,"*"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyz",0,"?"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("xyz",0,"?*"));
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!",5,"h*o"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello!",5,"h*x"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("hellxo",5,"h*o"));
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!",5,"he?lo"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello!",5,"he?xo"));
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!",5,"he??o"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("helllo!",5,"he?lo"));
|
||||||
|
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello world!",10,"he*o w*d"));
|
||||||
|
testOk1(epicsStrnGlobMatch("hello world!",11,"he*o w*d"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello world!",12,"he*o w*d"));
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello_world!",11,"he*o w*d"));
|
||||||
|
testOk1(epicsStrnGlobMatch("hello world!",11,"he**d"));
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("hello hello world!!!!!!!!!!!!!!!!!!!!",17,"he*o w*d"));
|
||||||
|
|
||||||
|
testOk1(!epicsStrnGlobMatch("hello hello world",15,"he*o w*d"));
|
||||||
|
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!!",5,"he*"));
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!!",5,"*lo"));
|
||||||
|
testOk1(epicsStrnGlobMatch("hello!!",5,"*"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -118,7 +155,7 @@ MAIN(epicsStringTest)
|
|||||||
char *s;
|
char *s;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
testPlan(401);
|
testPlan(427);
|
||||||
|
|
||||||
testChars();
|
testChars();
|
||||||
|
|
||||||
|
@ -8,9 +8,19 @@ RULES = $(EPICS_BASE)
|
|||||||
# RELEASE files point to other application tops
|
# RELEASE files point to other application tops
|
||||||
include $(TOP)/configure/RELEASE
|
include $(TOP)/configure/RELEASE
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||||
|
|
||||||
ifdef T_A
|
ifdef T_A
|
||||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Check EPICS_BASE is set properly
|
||||||
|
ifneq (file,$(origin EPICS_BASE))
|
||||||
|
$(error EPICS_BASE must be set in a configure/RELEASE file)
|
||||||
|
else
|
||||||
|
ifeq ($(wildcard $(EPICS_BASE)/configure/CONFIG_BASE),)
|
||||||
|
$(error EPICS_BASE does not point to an EPICS installation)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CONFIG = $(RULES)/configure
|
CONFIG = $(RULES)/configure
|
||||||
@ -19,11 +29,17 @@ include $(CONFIG)/CONFIG
|
|||||||
# Override the Base definition:
|
# Override the Base definition:
|
||||||
INSTALL_LOCATION = $(TOP)
|
INSTALL_LOCATION = $(TOP)
|
||||||
|
|
||||||
# CONFIG_SITE files contain other build configuration settings
|
# CONFIG_SITE files contain local build configuration settings
|
||||||
include $(TOP)/configure/CONFIG_SITE
|
include $(TOP)/configure/CONFIG_SITE
|
||||||
|
|
||||||
|
# Host-arch specific settings
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||||
|
|
||||||
ifdef T_A
|
ifdef T_A
|
||||||
|
# Target-arch specific settings
|
||||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||||
|
|
||||||
|
# Host & target specific settings
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
# CONFIG - Load build configuration data
|
# CONFIG - Load build configuration data
|
||||||
#
|
#
|
||||||
# Do not make changes in this file, any site-specific
|
# Do not make changes to this file!
|
||||||
# overrides should be given in a CONFIG_SITE file.
|
|
||||||
|
|
||||||
# Where the build rules come from
|
# Allow user to override where the build rules come from
|
||||||
RULES = $(EPICS_BASE)
|
RULES = $(EPICS_BASE)
|
||||||
|
|
||||||
INSTALL_IDLFILE = $(INSTALL)
|
# RELEASE files point to other application tops
|
||||||
|
|
||||||
include $(TOP)/configure/RELEASE
|
include $(TOP)/configure/RELEASE
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
|
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||||
@ -17,27 +15,38 @@ ifdef T_A
|
|||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Check EPICS_BASE is set properly
|
||||||
|
ifneq (file,$(origin EPICS_BASE))
|
||||||
|
$(error EPICS_BASE must be set in a configure/RELEASE file)
|
||||||
|
else
|
||||||
|
ifeq ($(wildcard $(EPICS_BASE)/configure/CONFIG_BASE),)
|
||||||
|
$(error EPICS_BASE does not point to an EPICS installation)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
CONFIG = $(RULES)/configure
|
CONFIG = $(RULES)/configure
|
||||||
include $(CONFIG)/CONFIG
|
include $(CONFIG)/CONFIG
|
||||||
|
|
||||||
# Override some Base definitions
|
# Override the Base definition:
|
||||||
INSTALL_LOCATION = $(TOP)
|
INSTALL_LOCATION = $(TOP)
|
||||||
|
|
||||||
# CONFIG_SITE files contain build configuration overrides
|
# CONFIG_SITE files contain local build configuration settings
|
||||||
include $(TOP)/configure/CONFIG_SITE
|
include $(TOP)/configure/CONFIG_SITE
|
||||||
|
|
||||||
# Host-arch specific settings
|
# Host-arch specific settings for extensions are in configure/os
|
||||||
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||||
|
|
||||||
|
ifdef T_A
|
||||||
|
# Target-arch specific settings for extensions are in configure/os
|
||||||
|
-include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A)
|
||||||
|
|
||||||
|
# Host & target specific settings for extensions are in configure/os
|
||||||
|
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Additional settings for extensions
|
||||||
|
INSTALL_IDLFILE = $(INSTALL)
|
||||||
|
|
||||||
ifdef INSTALL_LOCATION_EXTENSIONS
|
ifdef INSTALL_LOCATION_EXTENSIONS
|
||||||
INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS)
|
INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef T_A
|
|
||||||
# Target-arch specific settings
|
|
||||||
-include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A)
|
|
||||||
|
|
||||||
# Host & target specific combination settings
|
|
||||||
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
@ -227,6 +227,12 @@ sub envPaths {
|
|||||||
# Check RELEASE file consistency with support modules
|
# Check RELEASE file consistency with support modules
|
||||||
#
|
#
|
||||||
sub checkRelease {
|
sub checkRelease {
|
||||||
|
die "\nEPICS_BASE must be set in a configure/RELEASE file.\n\n"
|
||||||
|
unless grep(m/^(EPICS_BASE)$/, @apps) &&
|
||||||
|
exists $macros{EPICS_BASE} &&
|
||||||
|
$macros{EPICS_BASE} ne '' &&
|
||||||
|
-f "$macros{EPICS_BASE}/configure/CONFIG_BASE";
|
||||||
|
|
||||||
my $status = 0;
|
my $status = 0;
|
||||||
delete $macros{RULES};
|
delete $macros{RULES};
|
||||||
delete $macros{TOP};
|
delete $macros{TOP};
|
||||||
|
Reference in New Issue
Block a user