Compare commits

...

11 Commits

Author SHA1 Message Date
Janet Anderson
3009091875 Creating R3.14.12.3 2013-12-16 15:51:45 -06:00
Janet Anderson
6a0d5e0e87 Changed EPICS to Release 3.14.12.4 2013-12-16 15:48:54 -06:00
Andrew Johnson
97636a45e0 libCom: Remove epicsShareAPI from epicsExit APIs
Passing epicsExitCallAtExits into atexit() was generating
a warning about passing in a __stdcall routine pointer.
2013-12-16 14:52:29 -06:00
Andrew Johnson
a50c66b6ff libCom/test: Added epicsEnvTest.c
VxWorks 6.x can make environment variables private to each
thread, which doesn't work too well.
A test failure on VxWorks explains how to change the image
configuration to fix this.
2013-12-16 12:48:25 -06:00
Andrew Johnson
88ae947c84 configure: Refined how/when we pull in <top>/cfg files
Only read CONFIG* and RULES* files,
and only do so in build dirs, i.e. when T_A is defined.
2013-12-13 16:04:01 -06:00
Andrew Johnson
22540ac743 docs: Release note update.
Credit Peter Heesterman with windows build updates.
2013-12-11 18:11:51 -06:00
Andrew Johnson
197e992241 Fixed iocsh stream redirection for several commands
Eric provided the fixes to iocsh (empty commands would not reset
redirected streams), I fixed various commands.
2013-12-11 17:50:29 -06:00
Andrew Johnson
b0cf5c256a startup: Add cygwin-x86_64 to EpicsHostArch.pl script 2013-12-10 16:28:08 -06:00
Andrew Johnson
76e967c960 dbStatic: Fixed crash loading record of unknown type
Fixed segfault when dbLoadRecords tried to load a record of a
type that was not defined in its DBD files.
2013-12-04 17:37:42 -06:00
Andrew Johnson
4ac35ab85c docs: iPhone Simulator builds broken by Xcode 5
From Mark Engbretson, no known solution yet.
2013-12-04 10:37:44 -06:00
Janet Anderson
4209abe2cf Set snapshot to 3.14.12.4-rc1-DEV 2013-12-02 14:12:45 -06:00
19 changed files with 323 additions and 197 deletions

View File

@@ -1,17 +1,13 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
# EPICS BASE is distributed subject to a Software License Agreement found
# in the file LICENSE that is included with this distribution.
#*************************************************************************
#
# $Revision-Id$
#
# The developer may edit this file.
# assume T_A is the host arch if not specified
#
# Common build definitions
@@ -89,8 +85,6 @@ endif
-include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A)
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
# Include <top>/cfg/CONFIG* definitions from tops defined in RELEASE* files
#
ifneq ($(CONFIG),$(TOP)/configure)
@@ -103,12 +97,12 @@ endif
# Include $(INSTALL_CFG)/CONFIG* definitions
#
ifndef T_A
TOP_CFG_CONFIGS = $(wildcard $(INSTALL_CFG)/CONFIG*)
ifneq ($(TOP_CFG_CONFIGS),)
include $(TOP_CFG_CONFIGS)
endif
endif
endif # ifdef T_A
# User specific definitions
#
@@ -119,22 +113,3 @@ ifdef T_A
-include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH).$(T_A)
endif
# All options
# may be overridden here.
#
# EXAMPLES
# --------
# Build client objects statically ? must be either YES or NO
#STATIC_BUILD=NO
# Host build optimization, must be either YES or NO
#HOST_OPT=YES
# Cross build optimization, must be either YES or NO
#CROSS_OPT=YES
# Generate Verbose Compiler Warnings for host build, must be either YES or NO
#HOST_WARN=YES
# Generate Verbose Compiler Warnings for cross compile builds, must be either YES or NO
#CROSS_WARN=YES
#etc.
#CROSS_COMPILER_TARGET_ARCHS=vxWorks-68040

View File

@@ -38,11 +38,11 @@ EPICS_PATCH_LEVEL = 4
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
#EPICS_DEV_SNAPSHOT=-pre2-DEV
EPICS_DEV_SNAPSHOT=-rc1
#EPICS_DEV_SNAPSHOT=-rc1
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
#EPICS_DEV_SNAPSHOT=
EPICS_DEV_SNAPSHOT=
# No changes should be needed below here

View File

@@ -1,10 +1,10 @@
#*************************************************************************
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# 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 the file LICENSE that is included with this distribution.
# in the file LICENSE that is included with this distribution.
#*************************************************************************
# $Revision-Id$
#
@@ -12,7 +12,7 @@
#
# --------------------------------------------------------------
# Module developers can now define a new type of file, e.g. ABC,
# Module developers can now define a new type of file, e.g. ABC,
# so that files of type ABC will be installed into a directory
# defined by INSTALL_ABC. This is done by creating a new CONFIG<name>
# file, e.g. CONFIG_ABC, with the following lines:
@@ -24,8 +24,14 @@
# $(INSTALL_LOCATION). The file type ABC should be target
# architecture independent (alh files, medm files, edm files).
#
# Optional rules necessary for files of type ABC should be put in
# a RULES_ABC file.
# Files of type ABC are then installed into the INSTALL_ABC
# directory by adding a line like the following to a Makefile.
#
# ABC += <filename1> <filename2> <filename3>
#
# Rules necessary to create files of type ABC should be put in
# a RULES_ABC file. Variables used by those rules should appear
# in a CONFIG_ABC file.
#
# The module developer installs new CONFIG* or RULES* files
# into the directory $(INSTALL_LOCATION)/cfg by including the
@@ -33,16 +39,11 @@
#
# CFG += CONFIG_ABC RULES_ABC
#
# Files of type ABC are installed into INSTALL_ABC directory
# by adding a line like the following to a Makefile.
#
# ABC += <filename1> <filename2> <filename3>
#
# Files in $(INSTALL_LOCATION)/cfg directory are now included by
# the base config files so the definitions and rules are available
# for use by later src directory Makefiles in the same module or
# by other modules with a RELEASE line pointing to the TOP of
# the module with RULES_ABC.
# CONFIG and RULES files in the $(INSTALL_LOCATION)/cfg directory
# are included by the Base config files so their definitions and
# rules are available for use by later src directory Makefiles in
# the same module, or by other modules with a RELEASE line that
# points to the TOP of the module providing these files.
FILE_TYPE += ADL
INSTALL_ADL = $(INSTALL_LOCATION)/adl
@@ -59,6 +60,6 @@ INSTALL_EDL = $(INSTALL_LOCATION)/edl
FILE_TYPE += PERL_MODULES
INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl
INSTALLS_CFG= $(CFG:%= $(INSTALL_CFG)/%)
INSTALLS_CFG = $(CFG:%= $(INSTALL_CFG)/%)
DIRECTORY_TARGETS += $(foreach type, $(FILE_TYPE),$(INSTALL_$(type)))

View File

@@ -1,10 +1,10 @@
#*************************************************************************
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# 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 the file LICENSE that is included with this distribution.
# in the file LICENSE that is included with this distribution.
#*************************************************************************
# $Revision-Id$
#
@@ -36,13 +36,11 @@ endif
endif
#---------------------------------------------
# Include existing and new $(INSTALL_CFG)/* definitions
# Include our own $(INSTALL_CFG)/RULES* definitions
#
TOP_CFG_FILES = $(sort $(wildcard $(INSTALL_CFG)/RULES*) \
$(wildcard $(INSTALL_CFG)/CONFIG*) \
$(addprefix $(INSTALL_CFG)/,$(CFG)))
ifneq ($(TOP_CFG_FILES),)
include $(TOP_CFG_FILES)
TOP_CFG_RULES = $(wildcard $(INSTALL_CFG)/RULES*)
ifneq ($(TOP_CFG_RULES),)
include $(TOP_CFG_RULES)
endif
#---------------------------------------------------------------

View File

@@ -1,19 +1,56 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>EPICS Base R3.14.12.4-rc1 Release Notes</title>
<title>EPICS Base R3.14.12.4 Release Notes</title>
</head>
<body lang="en">
<h1 align="center">EPICS Base Release 3.14.12.4-rc1</h1>
<h1 align="center">EPICS Base Release 3.14.12.4</h1>
<h2 align="center">Changes between 3.14.12.3 and 3.14.12.4</h2>
<!-- Insert new items immediately below here ... -->
<h3>New test for environment variables</h3>
<p>A new test program epicsEnvTest has been added to the libCom tests which
checks environment variable APIs. It was written to confirm that threads see
environment variable values that have been set in their parent thread. VxWorks
6.x boot images must be configured with ENV_VAR_USE_HOOKS set to FALSE for the
correct behaviour to occur (a test failure on VxWorks explains this).</p>
<h3>Inclusion of &lt;top&gt;/cfg/* files refined</h3>
<p>The way the build system includes files installed in the &lt;top&gt;/cfg/*
directory has been cleaned up. Files whose names begin with CONFIG will now get
included by the CONFIG step, and files whose names begin with RULES will get
included in the RULES step. These files are only ever included when GNUMake is
working in an application build (O.) directory and T_A is defined, so they
cannot be used to create generic build targets at other levels.</p>
<p>Files whose names don't start with either CONFIG or RULES are no longer
included automatically, but such files can still be installed into
&lt;top&gt;/cfg by naming them in the CFG variable.</p>
<h3>Fixed iocsh stream redirection for several commands</h3>
<p>A number of iocsh commands did not respond correctly to redirection of their
output using the iocsh '>file' or '2>error-file' syntax, and redirecting an
empty command could create files with garbage names. There may still be a few
commands that do not properly redirect their output, please notify the core
developers if you discover any. Thanks to Eric Norum for the iocsh changes.</p>
<p>For externally developed commands, the simplest way to support redirection in
your C/C++ code is to <tt>#include "epicsStdioRedirect.h"</tt> instead of
<tt>stdio.h</tt>.</p>
<h3>Fixed crash on loading record instance of unknown type</h3>
<p>Fixed segfault when dbLoadRecords tried to load a record of a type that was
not defined in its DBD files.</p>
<h3>Hex literal support in epicStrtod()</h3>
<p>Some OS implementations of the standard C library routine strtod() do not
@@ -26,6 +63,12 @@ Dirk Zimoch for suggesting this change.</p>
<p>Both windows-x64-mingw and cygwin-x86_64 build targets are now provided.</p>
<h3>Windows build issues</h3>
<p>Thanks to Peter Heesterman for suggesting a number of small changes that
clean up build issues on Windows, mostly related to symbol import and export
to/from DLLs.</p>
<h3>CAS: GDD Reference Count Underflow</h3>
<p>Thanks to Bruce Hill a source of an underflow in a GDD reference count in the
@@ -34,7 +77,9 @@ CAS code has been fixed.</p>
<h3>Support for Apple Xcode 5.0</h3>
<p>This adds the ability to build for iOS 7.0 and the ARMv8 64-bit CPU on the
newest iPhone 5S device.</p>
newest iPhone 5S device. Unfortunately the Xcode upgrade breaks the build of the
ios-x86 simulator target, although the ios-arm target successfully builds code
which runs fine on the real hardware.</p>
<h3>Reading TSEL field</h3>

View File

@@ -22,12 +22,12 @@
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "envDefs.h"
#include "epicsAssert.h"
#include "epicsStdioRedirect.h"
#include "errlog.h"
#include "osiWireFormat.h"

View File

@@ -14,7 +14,7 @@
* simple stub for testing monitors
*/
#include <stdio.h>
#include "epicsStdioRedirect.h"
#define epicsExportSharedSymbols
#include "cadef.h"

View File

@@ -112,8 +112,6 @@ static void yyerrorAbort(char *str)
{
yyerror(str);
yyAbort = TRUE;
while (ellCount(&tempList))
popFirstTemp();
}
static void allocTemp(void *pvoid)
@@ -256,6 +254,11 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
my_buffer_ptr = my_buffer;
ellAdd(&inputFileList,&pinputFile->node);
status = pvt_yy_parse();
if (yyAbort)
while (ellCount(&tempList))
popFirstTemp();
dbFreePath(pdbbase);
if(!status) { /*add RTYP and VERS as an attribute */
DBENTRY dbEntry;
@@ -923,7 +926,7 @@ static void dbRecordHead(char *recordType, char *name, int visible)
allocTemp(pdbentry);
status = dbFindRecordType(pdbentry, recordType);
if (status) {
epicsPrintf("Record \"%s\" is of unknown type \"%s\" - ",
epicsPrintf("Record \"%s\" is of unknown type \"%s\"\n",
name, recordType);
yyerrorAbort(NULL);
return;
@@ -932,8 +935,8 @@ static void dbRecordHead(char *recordType, char *name, int visible)
status = dbCreateRecord(pdbentry,name);
if (status==S_dbLib_recExists) {
if (strcmp(recordType, dbGetRecordTypeName(pdbentry))!=0) {
epicsPrintf("Record \"%s\" already defined with different type "
"\"%s\"\n", name, dbGetRecordTypeName(pdbentry));
epicsPrintf("Record \"%s\" of type \"%s\" redefined with new type "
"\"%s\"\n", name, dbGetRecordTypeName(pdbentry), recordType);
yyerror(NULL);
duplicate = TRUE;
return;

View File

@@ -9,8 +9,7 @@
/* $Revision-Id$ */
/* Author: Marty Kraimer Date: 04-07-94 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
@@ -18,6 +17,7 @@
#define epicsExportSharedSymbols
#include "cantProceed.h"
#include "epicsMutex.h"
#include "epicsStdioRedirect.h"
#include "epicsString.h"
#include "dbDefs.h"
#include "ellLib.h"
@@ -34,13 +34,14 @@ typedef struct gphPvt {
#define MIN_SIZE 256
#define DEFAULT_SIZE 512
#define MAX_SIZE 65536
void epicsShareAPI gphInitPvt(gphPvt **ppvt, int size)
{
gphPvt *pgphPvt;
if (size & (size - 1)) {
printf("gphInitPvt: %d is not a power of 2\n", size);
fprintf(stderr, "gphInitPvt: %d is not a power of 2\n", size);
size = DEFAULT_SIZE;
}
@@ -88,7 +89,7 @@ GPHENTRY * epicsShareAPI gphFind(gphPvt *pgphPvt, const char *name, void *pvtid)
epicsMutexUnlock(pgphPvt->lock);
return pgphNode;
}
GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
{
ELLLIST **paplist;
@@ -127,7 +128,7 @@ GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
epicsMutexUnlock(pgphPvt->lock);
return (pgphNode);
}
void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid)
{
ELLLIST **paplist;
@@ -161,7 +162,7 @@ void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid)
epicsMutexUnlock(pgphPvt->lock);
return;
}
void epicsShareAPI gphFreeMem(gphPvt *pgphPvt)
{
ELLLIST **paplist;
@@ -203,9 +204,10 @@ void epicsShareAPI gphDumpFP(FILE *fp, gphPvt *pgphPvt)
ELLLIST **paplist;
int h;
if (pgphPvt == NULL) return;
if (pgphPvt == NULL)
return;
printf("Hash table has %d buckets", pgphPvt->size);
fprintf(fp, "Hash table has %d buckets", pgphPvt->size);
paplist = pgphPvt->paplist;
for (h = 0; h < pgphPvt->size; h++) {

View File

@@ -3,8 +3,7 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* iocsh.cpp */
@@ -68,6 +67,7 @@ struct iocshRedirect {
const char *mode;
FILE *fp;
FILE *oldFp;
int mustRestore;
};
/*
@@ -101,7 +101,8 @@ iocshTableUnlock (void)
/*
* Register a command
*/
void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, iocshCallFunc func)
void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef,
iocshCallFunc func)
{
struct iocshCommand *l, *p, *n;
int i;
@@ -118,7 +119,8 @@ void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, iocshCallFu
if (i < 0)
break;
}
n = (struct iocshCommand *)callocMustSucceed (1, sizeof *n, "iocshRegister");
n = (struct iocshCommand *) callocMustSucceed (1, sizeof *n,
"iocshRegister");
if (!registryAdd(iocshCmdID, piocshFuncDef->name, (void *)n)) {
free (n);
iocshTableUnlock ();
@@ -162,7 +164,8 @@ void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef)
for (l = NULL, p = iocshVariableHead ; p != NULL ; l = p, p = p->next) {
i = strcmp (piocshVarDef->name, p->pVarDef->name);
if (i == 0) {
errlogPrintf("Warning -- iocshRegisterVariable redefining %s.\n", piocshVarDef->name);
errlogPrintf("Warning: iocshRegisterVariable redefining %s.\n",
piocshVarDef->name);
p->pVarDef = piocshVarDef;
found = 1;
break;
@@ -171,11 +174,13 @@ void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef)
break;
}
if (!found) {
n = (struct iocshVariable *)callocMustSucceed(1, sizeof *n, "iocshRegisterVariable");
n = (struct iocshVariable *) callocMustSucceed(1, sizeof *n,
"iocshRegisterVariable");
if (!registryAdd(iocshVarID, piocshVarDef->name, (void *)n)) {
free(n);
iocshTableUnlock();
errlogPrintf("iocshRegisterVariable failed to add %s.\n", piocshVarDef->name);
errlogPrintf("iocshRegisterVariable failed to add %s.\n",
piocshVarDef->name);
return;
}
if (l == NULL) {
@@ -225,14 +230,15 @@ showError (const char *filename, int lineno, const char *msg, ...)
va_start (ap, msg);
if (filename)
fprintf (stderr, "%s -- Line %d -- ", filename, lineno);
vfprintf (stderr, msg, ap);
fputc ('\n', stderr);
fprintf(epicsGetStderr(), "%s line %d: ", filename, lineno);
vfprintf (epicsGetStderr(), msg, ap);
fputc ('\n', epicsGetStderr());
va_end (ap);
}
static int
cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const iocshArg *piocshArg)
cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf,
const iocshArg *piocshArg)
{
char *endp;
@@ -245,12 +251,13 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const
errno = 0;
argBuf->ival = strtoul (arg, &endp, 0);
if (errno == ERANGE) {
showError (filename, lineno, "Integer '%s' out of range", arg);
showError(filename, lineno, "Integer '%s' out of range",
arg);
return 0;
}
}
if (*endp) {
showError (filename, lineno, "Illegal integer '%s'", arg);
showError(filename, lineno, "Illegal integer '%s'", arg);
return 0;
}
}
@@ -263,7 +270,7 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const
if (arg && *arg) {
argBuf->dval = epicsStrtod (arg, &endp);
if (*endp) {
showError (filename, lineno, "Illegal double '%s'", arg);
showError(filename, lineno, "Illegal double '%s'", arg);
return 0;
}
}
@@ -279,7 +286,7 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const
case iocshArgPersistentString:
argBuf->sval = epicsStrDup(arg);
if (argBuf->sval == NULL) {
showError (filename, lineno, "Out of memory");
showError(filename, lineno, "Out of memory");
return 0;
}
break;
@@ -288,17 +295,18 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const
/* Argument must be missing or 0 or pdbbase */
if(!arg || !*arg || (*arg == '0') || (strcmp(arg, "pdbbase") == 0)) {
if(!iocshPpdbbase || !*iocshPpdbbase) {
showError (filename, lineno, "pdbbase not present");
showError(filename, lineno, "pdbbase not present");
return 0;
}
argBuf->vval = *iocshPpdbbase;
break;
}
showError (filename, lineno, "Expecting 'pdbbase' got '%s'", arg);
showError(filename, lineno, "Expecting 'pdbbase' got '%s'", arg);
return 0;
default:
showError (filename, lineno, "Illegal argument type %d", piocshArg->type);
showError(filename, lineno, "Illegal argument type %d",
piocshArg->type);
return 0;
}
return 1;
@@ -329,6 +337,7 @@ openRedirect(const char *filename, int lineno, struct iocshRedirect *redirect)
}
return -1;
}
redirect->mustRestore = 0;
}
}
return 0;
@@ -349,14 +358,17 @@ startRedirect(const char * /*filename*/, int /*lineno*/,
case 0:
redirect->oldFp = epicsGetThreadStdin();
epicsSetThreadStdin(redirect->fp);
redirect->mustRestore = 1;
break;
case 1:
redirect->oldFp = epicsGetThreadStdout();
epicsSetThreadStdout(redirect->fp);
redirect->mustRestore = 1;
break;
case 2:
redirect->oldFp = epicsGetThreadStderr();
epicsSetThreadStderr(redirect->fp);
redirect->mustRestore = 1;
break;
}
}
@@ -377,10 +389,12 @@ stopRedirect(const char *filename, int lineno, struct iocshRedirect *redirect)
showError(filename, lineno, "Error closing \"%s\": %s.",
redirect->name, strerror(errno));
redirect->fp = NULL;
switch(i) {
case 0: epicsSetThreadStdin(redirect->oldFp); break;
case 1: epicsSetThreadStdout(redirect->oldFp); break;
case 2: epicsSetThreadStderr(redirect->oldFp); break;
if (redirect->mustRestore) {
switch(i) {
case 0: epicsSetThreadStdin(redirect->oldFp); break;
case 1: epicsSetThreadStdout(redirect->oldFp); break;
case 2: epicsSetThreadStderr(redirect->oldFp); break;
}
}
}
redirect->name = NULL;
@@ -404,30 +418,31 @@ static void helpCallFunc(const iocshArgBuf *args)
if (argc == 1) {
int l, col = 0;
printf ("Type 'help command_name' to get more information about a particular command.\n");
fprintf(epicsGetStdout(),
"Type 'help <command>' to see the arguments of <command>.\n");
iocshTableLock ();
for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) {
piocshFuncDef = pcmd->pFuncDef;
l = strlen (piocshFuncDef->name);
if ((l + col) >= 79) {
fputc ('\n', stdout);
fputc('\n', epicsGetStdout());
col = 0;
}
fputs (piocshFuncDef->name, stdout);
fputs(piocshFuncDef->name, epicsGetStdout());
col += l;
if (col >= 64) {
fputc ('\n', stdout);
fputc('\n', epicsGetStdout());
col = 0;
}
else {
do {
fputc (' ', stdout);
fputc(' ', epicsGetStdout());
col++;
} while ((col % 16) != 0);
}
}
if (col)
fputc ('\n', stdout);
fputc('\n', epicsGetStdout());
iocshTableUnlock ();
}
else {
@@ -435,18 +450,18 @@ static void helpCallFunc(const iocshArgBuf *args)
for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) {
piocshFuncDef = pcmd->pFuncDef;
if (epicsStrGlobMatch(piocshFuncDef->name, argv[iarg]) != 0) {
fputs (piocshFuncDef->name, stdout);
fputs(piocshFuncDef->name, epicsGetStdout());
for (int a = 0 ; a < piocshFuncDef->nargs ; a++) {
const char *cp = piocshFuncDef->arg[a]->name;
if ((piocshFuncDef->arg[a]->type == iocshArgArgv)
|| (strchr (cp, ' ') == NULL)) {
fprintf (stdout, " %s", cp);
fprintf(epicsGetStdout(), " %s", cp);
}
else {
fprintf (stdout, " '%s'", cp);
fprintf(epicsGetStdout(), " '%s'", cp);
}
}
fprintf (stdout,"\n");;
fprintf(epicsGetStdout(),"\n");;
}
}
}
@@ -478,7 +493,6 @@ iocshBody (const char *pathname, const char *commandLine)
iocshArgBuf *argBuf = NULL;
int argBufCapacity = 0;
struct iocshCommand *found;
struct iocshFuncDef const *piocshFuncDef;
void *readlineContext = NULL;
int wasOkToBlock;
@@ -493,7 +507,8 @@ iocshBody (const char *pathname, const char *commandLine)
else {
fp = fopen (pathname, "r");
if (fp == NULL) {
fprintf (stderr, "Can't open %s: %s\n", pathname, strerror (errno));
fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname,
strerror (errno));
return -1;
}
if ((filename = strrchr (pathname, '/')) == NULL)
@@ -507,7 +522,7 @@ iocshBody (const char *pathname, const char *commandLine)
* Create a command-line input context
*/
if ((readlineContext = epicsReadlineBegin(fp)) == NULL) {
fprintf(stderr, "Can't allocate command-line object.\n");
fprintf(epicsGetStderr(), "Can't allocate command-line object.\n");
if (fp)
fclose(fp);
return -1;
@@ -519,7 +534,7 @@ iocshBody (const char *pathname, const char *commandLine)
*/
redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects);
if (redirects == NULL) {
printf ("Out of memory!\n");
fprintf(epicsGetStderr(), "Out of memory!\n");
return -1;
}
@@ -604,7 +619,7 @@ iocshBody (const char *pathname, const char *commandLine)
argvCapacity += 50;
av = (char **)realloc (argv, argvCapacity * sizeof *argv);
if (av == NULL) {
printf ("Out of memory!\n");
fprintf (epicsGetStderr(), "Out of memory!\n");
argc = -1;
break;
}
@@ -699,17 +714,17 @@ iocshBody (const char *pathname, const char *commandLine)
backslash = 0;
}
if (redirect != NULL) {
showError (filename, lineno, "Illegal redirection.");
showError(filename, lineno, "Illegal redirection.");
continue;
}
if (argc < 0)
break;
if (quote != EOF) {
showError (filename, lineno, "Unbalanced quote.");
showError(filename, lineno, "Unbalanced quote.");
continue;
}
if (backslash) {
showError (filename, lineno, "Trailing backslash.");
showError(filename, lineno, "Trailing backslash.");
continue;
}
if (inword)
@@ -730,73 +745,68 @@ iocshBody (const char *pathname, const char *commandLine)
stopRedirect(filename, lineno, redirects);
continue;
}
if (openRedirect(filename, lineno, redirects) < 0)
continue;
/*
* Look up command
* Special command?
*/
if (argc) {
/*
* Special command?
*/
if (strncmp (argv[0], "exit", 4) == 0)
break;
if ((strcmp (argv[0], "?") == 0)
|| (strncmp (argv[0], "help", 4) == 0)) {
}
if ((argc > 0) && (strcmp(argv[0], "exit") == 0))
break;
/*
* Set up redirection
*/
if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) {
/*
* Look up command
*/
found = (iocshCommand *)registryFind (iocshCmdID, argv[0]);
if (!found) {
showError (filename, lineno, "Command %s not found.", argv[0]);
continue;
}
piocshFuncDef = found->pFuncDef;
/*
* Process arguments and call function
*/
for (int iarg = 0 ; ; ) {
if (iarg == piocshFuncDef->nargs) {
startRedirect(filename, lineno, redirects);
(*found->func)(argBuf);
stopRedirect(filename, lineno, redirects);
break;
}
if (iarg >= argBufCapacity) {
void *np;
argBufCapacity += 20;
np = realloc (argBuf, argBufCapacity * sizeof *argBuf);
if (np == NULL) {
fprintf (stderr, "Out of memory!\n");
argBufCapacity -= 20;
if (found) {
/*
* Process arguments and call function
*/
struct iocshFuncDef const *piocshFuncDef = found->pFuncDef;
for (int iarg = 0 ; ; ) {
if (iarg == piocshFuncDef->nargs) {
startRedirect(filename, lineno, redirects);
(*found->func)(argBuf);
break;
}
argBuf = (iocshArgBuf *)np;
if (iarg >= argBufCapacity) {
void *np;
argBufCapacity += 20;
np = realloc (argBuf, argBufCapacity * sizeof *argBuf);
if (np == NULL) {
fprintf (epicsGetStderr(), "Out of memory!\n");
argBufCapacity -= 20;
break;
}
argBuf = (iocshArgBuf *)np;
}
if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) {
argBuf[iarg].aval.ac = argc-iarg;
argBuf[iarg].aval.av = argv+iarg;
iarg = piocshFuncDef->nargs;
}
else {
if (!cvtArg (filename, lineno,
((iarg < argc) ? argv[iarg+1] : NULL),
&argBuf[iarg], piocshFuncDef->arg[iarg]))
break;
iarg++;
}
}
if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) {
argBuf[iarg].aval.ac = argc-iarg;
argBuf[iarg].aval.av = argv+iarg;
iarg = piocshFuncDef->nargs;
}
else {
if (!cvtArg (filename, lineno,
((iarg < argc) ? argv[iarg+1] : NULL),
&argBuf[iarg], piocshFuncDef->arg[iarg]))
break;
iarg++;
if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) {
const char *newPrompt;
if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL)
prompt = newPrompt;
}
}
if((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) {
const char *newPrompt;
if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL)
prompt = newPrompt;
else {
showError(filename, lineno, "Command %s not found.", argv[0]);
}
}
stopRedirect(filename, lineno, redirects);
}
if (fp && (fp != stdin))
fclose (fp);
@@ -840,7 +850,8 @@ static void varHandler(const iocshVarDef *v, const char *setString)
{
switch(v->type) {
default:
printf("Can't handle variable %s of type %d.\n", v->name, v->type);
fprintf(epicsGetStderr(), "Can't handle variable %s of type %d.\n",
v->name, v->type);
return;
case iocshArgInt: break;
case iocshArgDouble: break;
@@ -849,10 +860,10 @@ static void varHandler(const iocshVarDef *v, const char *setString)
switch(v->type) {
default: break;
case iocshArgInt:
printf("%s = %d\n", v->name, *(int *)v->pval);
fprintf(epicsGetStdout(), "%s = %d\n", v->name, *(int *)v->pval);
break;
case iocshArgDouble:
printf("%s = %g\n", v->name, *(double *)v->pval);
fprintf(epicsGetStdout(), "%s = %g\n", v->name, *(double *)v->pval);
break;
}
}
@@ -866,7 +877,8 @@ static void varHandler(const iocshVarDef *v, const char *setString)
if((*setString != '\0') && (*endp == '\0'))
*(int *)v->pval = ltmp;
else
printf("Invalid value -- value of %s not changed.\n", v->name);
fprintf(epicsGetStderr(),
"Invalid integer value. Var %s not changed.\n", v->name);
break;
}
case iocshArgDouble:
@@ -876,7 +888,8 @@ static void varHandler(const iocshVarDef *v, const char *setString)
if((*setString != '\0') && (*endp == '\0'))
*(double *)v->pval = dtmp;
else
printf("Invalid value -- value of %s not changed.\n", v->name);
fprintf(epicsGetStderr(),
"Invalid double value. Var %s not changed.\n", v->name);
break;
}
}
@@ -893,7 +906,7 @@ static void varCallFunc(const iocshArgBuf *args)
else {
v = (iocshVariable *)registryFind(iocshVarID, args[0].sval);
if (v == NULL) {
printf("%s -- no such variable.\n", args[0].sval);
fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval);
}
else {
varHandler(v->pVarDef, args[1].sval);
@@ -916,7 +929,8 @@ static void iocshCmdCallFunc(const iocshArgBuf *args)
*/
/* comment */
static const iocshArg commentArg0 = { "newline-terminated comment",iocshArgArgv};
static const iocshArg commentArg0 = { "newline-terminated comment",
iocshArgArgv};
static const iocshArg *commentArgs[1] = {&commentArg0};
static const iocshFuncDef commentFuncDef = {"#",1,commentArgs};
static void commentCallFunc(const iocshArgBuf *)

View File

@@ -9,10 +9,10 @@
\*************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#define epicsExportSharedSymbols
#include "iocsh.h"
#include "epicsStdioRedirect.h"
#include "epicsTime.h"
#include "epicsThread.h"
#include "epicsMutex.h"
@@ -60,7 +60,7 @@ static void chdirCallFunc(const iocshArgBuf *args)
int status;
status = chdir(args[0].sval);
if (status) {
printf ("Invalid directory path ignored\n");
fprintf(stderr, "Invalid directory path, ignored\n");
}
}
@@ -86,11 +86,11 @@ static void epicsEnvSetCallFunc(const iocshArgBuf *args)
char *value = args[1].sval;
if (name == NULL) {
printf ("Missing environment variable name argument.\n");
fprintf(stderr, "Missing environment variable name argument.\n");
return;
}
if (value == NULL) {
printf ("Missing environment variable value argument.\n");
fprintf(stderr, "Missing environment variable value argument.\n");
return;
}
epicsEnvSet (name, value);
@@ -231,7 +231,7 @@ static void threadCallFunc(const iocshArgBuf *args)
if (*endp) {
tid = epicsThreadGetId (cp);
if (!tid) {
printf ("\t'%s' is not a known thread name\n", cp);
fprintf(stderr, "\t'%s' is not a known thread name\n", cp);
continue;
}
}
@@ -299,7 +299,7 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args)
if (*endp) {
tid = epicsThreadGetId(cp);
if (!tid) {
printf("*** argument %d (%s) is not a valid thread name ***\n", i, cp);
fprintf(stderr, "'%s' is not a valid thread name\n", cp);
continue;
}
}
@@ -307,13 +307,13 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args)
tid =(epicsThreadId)ltmp;
epicsThreadGetName(tid, nameBuf, sizeof nameBuf);
if (nameBuf[0] == '\0') {
printf("*** argument %d (%s) is not a valid thread id ***\n", i, cp);
fprintf(stderr, "'%s' is not a valid thread id\n", cp);
continue;
}
}
if (!epicsThreadIsSuspended(tid)) {
printf("*** Thread %s is not suspended ***\n", cp);
fprintf(stderr, "Thread %s is not suspended\n", cp);
continue;
}
epicsThreadResume(tid);

View File

@@ -83,7 +83,7 @@ static void epicsExitCallAtExitsPvt ( exitPvt * pep )
}
}
epicsShareFunc void epicsShareAPI epicsExitCallAtExits ( void )
epicsShareFunc void epicsExitCallAtExits ( void )
{
exitPvt * pep = 0;
epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 );
@@ -99,7 +99,7 @@ epicsShareFunc void epicsShareAPI epicsExitCallAtExits ( void )
}
}
epicsShareFunc void epicsShareAPI epicsExitCallAtThreadExits ( void )
epicsShareFunc void epicsExitCallAtThreadExits ( void )
{
exitPvt * pep;
epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 );
@@ -126,7 +126,7 @@ static int epicsAtExitPvt (
return status;
}
epicsShareFunc int epicsShareAPI epicsAtThreadExit (
epicsShareFunc int epicsAtThreadExit (
epicsExitFunc func, void *arg )
{
exitPvt * pep;
@@ -142,7 +142,7 @@ epicsShareFunc int epicsShareAPI epicsAtThreadExit (
return epicsAtExitPvt ( pep, func, arg );
}
epicsShareFunc int epicsShareAPI epicsAtExit(
epicsShareFunc int epicsAtExit(
epicsExitFunc func, void *arg )
{
int status = -1;
@@ -155,7 +155,7 @@ epicsShareFunc int epicsShareAPI epicsAtExit(
return status;
}
epicsShareFunc void epicsShareAPI epicsExit(int status)
epicsShareFunc void epicsExit(int status)
{
epicsExitCallAtExits();
epicsThreadSleep(1.0);

View File

@@ -16,13 +16,12 @@
extern "C" {
#endif
epicsShareFunc void epicsShareAPI epicsExit(int status);
epicsShareFunc void epicsShareAPI epicsExitCallAtExits(void);
epicsShareFunc int epicsShareAPI epicsAtExit(
void (*epicsExitFunc)(void *arg),void *arg);
epicsShareFunc void epicsExit(int status);
epicsShareFunc void epicsExitCallAtExits(void);
epicsShareFunc int epicsAtExit(void (*epicsExitFunc)(void *arg),void *arg);
epicsShareFunc void epicsShareAPI epicsExitCallAtThreadExits(void);
epicsShareFunc int epicsShareAPI epicsAtThreadExit(
epicsShareFunc void epicsExitCallAtThreadExits(void);
epicsShareFunc int epicsAtThreadExit(
void (*epicsExitFunc)(void *arg),void *arg);

View File

@@ -9,7 +9,6 @@
/* Original Authors: David H. Thompson & Sheng Peng (ORNL) */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -19,6 +18,7 @@
#include "epicsMutex.h"
#include "epicsMessageQueue.h"
#include "epicsString.h"
#include "epicsStdioRedirect.h"
#include "epicsThread.h"
#include "epicsTime.h"
#include "epicsTimer.h"

View File

@@ -22,7 +22,7 @@
#include "dbDefs.h"
#include "epicsEvent.h"
#include "epicsExit.h"
#include "epicsStdio.h"
#include "epicsStdioRedirect.h"
#include "epicsThread.h"
#include "epicsMutex.h"
#include "errlog.h"

View File

@@ -37,6 +37,11 @@ epicsEllTest_SRCS += epicsEllTest.c
testHarness_SRCS += epicsEllTest.c
TESTS += epicsEllTest
TESTPROD_HOST += epicsEnvTest
epicsEnvTest_SRCS += epicsEnvTest.c
testHarness_SRCS += epicsEnvTest.c
TESTS += epicsEnvTest
TESTPROD_HOST += epicsErrlogTest
epicsErrlogTest_SRCS += epicsErrlogTest.c
testHarness_SRCS += epicsErrlogTest.c

View File

@@ -0,0 +1,78 @@
/*************************************************************************\
* Copyright (c) 2013 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.
\*************************************************************************/
/* epicsEnvTest.c */
/* Author: Andrew Johnson
* Date: 2013-12-13
*/
/* Check environment variable APIs.
* TODO: Add tests for envDefs.h routines.
*
* The thread test is needed on VxWorks 6.x, where the OS can be
* configured to maintain separate, totally independent sets
* of environment variables for each thread. This configuration
* is not supported by EPICS which expects child threads to at
* least inherit the partent thread's environment variables.
*/
#include <stdlib.h>
#include <string.h>
#include "envDefs.h"
#include "epicsThread.h"
#include "epicsUnitTest.h"
#include "testMain.h"
#define PARENT "Parent"
#define CHILD "Child"
static void child(void *arg)
{
const char *value = getenv(PARENT);
if (!testOk(value && (strcmp(value, PARENT) == 0),
"Child thread sees parent environment values")) {
#ifdef vxWorks
testDiag("VxWorks image needs ENV_VAR_USE_HOOKS configured as FALSE");
#else
testDiag("Check OS configuration, environment inheritance needed");
#endif
}
epicsEnvSet(CHILD, CHILD);
}
MAIN(epicsEnvTest)
{
unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall);
const char *value;
testPlan(3);
epicsEnvSet(PARENT, PARENT);
value = getenv(PARENT);
if (!testOk(value && (strcmp(value, PARENT) == 0),
"epicsEnvSet correctly modifies environment"))
testAbort("environment variables not working");
epicsThreadCreate("child", 50, stackSize, child, NULL);
epicsThreadSleep(0.1);
value = getenv(CHILD);
if (value && (strcmp(value, CHILD) == 0))
testDiag("Child and parent threads share a common environment");
value = getenv(PARENT);
testOk(value && (strcmp(value, PARENT) == 0),
"PARENT environment variable not modified");
testDone();
return 0;
}

View File

@@ -20,6 +20,7 @@ int epicsThreadTest(void);
int epicsTimerTest(void);
int epicsAlgorithm(void);
int epicsEllTest(void);
int epicsEnvTest(void);
int epicsErrlogTest(void);
int epicsCalcTest(void);
int epicsEventTest(void);
@@ -60,6 +61,8 @@ void epicsRunLibComTests(void)
runTest(epicsEllTest);
runTest(epicsEnvTest);
runTest(epicsErrlogTest);
runTest(epicsCalcTest);

View File

@@ -31,7 +31,10 @@ sub GetEpicsHostArch { # no args
} elsif ($arch =~ m/arm-linux/) { return "linux-arm";
} elsif ($arch =~ m/MSWin32-x86/) { return "win32-x86";
} elsif ($arch =~ m/MSWin32-x64/) { return "windows-x64";
} elsif ($arch =~ m/cygwin/) { return "cygwin-x86";
} elsif ($arch =~ m/cygwin/) {
my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname();
if ($cpu =~ m/x86_64/) { return "cygwin-x86_64"; }
return "cygwin-x86";
} elsif ($arch =~ m/darwin/) {
my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname();
if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; }